Spring provides programmatic transaction management, with the corresponding template class org. Springframework. Transaction. Support. TransactionTemplate, can deal with some special needs.

TransactionTemplate is thread-safe, so you can share TransactionTemplate instances across multiple classes for transaction management.

TransactionTemplate inherited DefaultTransactionDefinition, so also has a variety of ways to set up the transaction attribute:

The main methods of the TransactionTemplate class:

methods instructions
public void setTransactionManager(PlatformTransactionManager transactionManager) Set up the transaction manager.
public <T> T execute(TransactionCallback<T> action) In the TransactionCallback callback interface, code the data access logic that needs to be executed transactionally.

The TransactionCallback interface defines only one method, doInTransaction(TransactionStatus Status). Spring also defines an abstract class TransactionCallbackWithoutResult, used to perform only, but I don’t need to return the result.

Spring configuration file:

<? xml version="1.0" encoding="UTF-8"? > <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <! <context:component-scan base-package="net.deniro.xxx.transaction"/ > <! -- Data source --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close"
          p:driverClassName="com.mysql.jdbc.Driver"
          p:url="JDBC: mysql: / / 127.0.0.1:3306 / XXX"
          p:username="root"
          p:password="xxx"/ > <! -- JDBC template --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
          p:dataSource-ref="dataSource"/ > <! -- transaction manager --> <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
          p:dataSource-ref="dataSource"/ > <! -- Transaction template --> <bean id="TransactionTemplate"
          class="org.springframework.transaction.support.TransactionTemplate"
          p:transactionManager-ref="transactionManager"/>

</beans>
Copy the code

The User class:

public class User {
    private long id;
    private String name;

    public User(String name) {
        this.name = name;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) { this.name = name; }}Copy the code

UserDao class:

@Repository public class UserDao { @Autowired private JdbcTemplate jdbcTemplate; /** * save account ** @param user * @throws SQLException */ public void save(user user) {String SQL ="insert into t_user(user_name) values(?) ";
        jdbcTemplate.update(sql, user.getName());

        String sql2 = "insert into t_log(user_name) values(?) "; jdbcTemplate.update(sql2, user.getName()); }}Copy the code

To test whether the transaction works, here the first SQL is correct and the second SQL is wrong (table not found).

UserService class:

@Service
public class UserService {

    @Autowired
    private UserDao userDao;


    @Autowired
    private TransactionTemplate template;


    public void save(final User user) {
        template.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) { userDao.save(user); }}); }}Copy the code

Unit tests:

public class UserServiceTest {

    ApplicationContext context;

    @BeforeMethod
    public void setUp() throws Exception {
        context = new ClassPathXmlApplicationContext("spring.xml");
    }

    @Test
    public void test() {
        UserService userService = (UserService) context.getBean("userService");
        final User user = new User("deniro"); userService.save(user); }}Copy the code

To see the Spring transaction log, we can change the log4J transaction configuration to DEBUG:

log4j.logger.org.springframework.jdbc.datasource.DataSourceTransactionManager=DEBUG
log4j.logger.org.springframework.transaction.interceptor=DEBUG
log4j.logger.org.springframework.transaction=DEBUG
Copy the code

Analysis of operation results:

Spring first creates a new transaction.

On execution of the second SQL statement, an exception is thrown; Spring performs a rollback. Note The transaction takes effect