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