事务主要是针对数据库而言,在Spring中使用一般也是针对数据库。简单来说,就是一系列的事情要么全部完成,要么都不完成。事务有四个性质,即ACID。
原子性(Atomicity):多个事情是作为一个原子发生的,要么同时完成,要么都不发生。
一致性(Consistency):事务的执行使得数据库从一种正确状态转换成另一种正确状态
隔离性(Isolation): 事务之间是隔离的,即在事务正确提交之前,它可能的结果不会显示给任何其他事务。隔离级别有四种级别,读未提交(Read uncommitted),读提交(read committed),可重复读(repeatable read)和串行化(Serializable)。MySQL数据库默认的隔离级别是可重复读。
持久性(Durability):事务提交以后,其结果永久保存在数据库中。
概要
本篇主要介绍事务如何在spring boot中使用,在spring cloud的中也是类似的用法。整个web项目采用的主题框架是spring boot + mybatis。
Spring 事务属性分析
Spring 事务管理API分析
Spring 中编程式事务管理
事务定义
首先我们要在Spring中定义一个事务模板配置类,内容如下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40package com.ll.blog;
import com.ll.blog.transaction.TransactionTemplateComponent;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
import javax.sql.DataSource;
* 事务模板配置器
*
* @author leon
* @since 2019/7/11 14:30
*/
@Configuration
public class{
@Resource(name = "transactionManager")
private DataSourceTransactionManager transactionManager;
@Bean(name = "transactionManager")
DataSourceTransactionManager transactionManager(DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "aTransactionTemplate")
TransactionTemplate transactionTemplate(){
return new TransactionTemplate(transactionManager, new DefaultTransactionDefinition());
}
@Bean(name = "transactionTemplateComponent")
TransactionTemplateComponent transactionTemplateComponent(){
return new TransactionTemplateComponent(transactionTemplate());
}
}
@EnableTransactionManagement注解表示开启声明式的事务。@Configuration注解表示此类(TransactionTemplateConfigurator)是一个配置类,如果之前使用过SSM(spring+springMVC+mybatis),[email protected]ns,[email protected]@[email protected]ager,[email protected]ean注解表示spring容器中的bean对象。
在方法transactionManager中,我们看到入参是dataSource,而这个对象我们并没有在程序中显示的创建,同时也没有注入它。这是因为spring boot如果跟mybatis结合,spring boot会自动根据配置文件中的内容为我们创建一个DataSource的bean。
其中使用了默认的事务定义类DefaultTransactionDefinition。我们可以具体查看它对于事务具体的配置。
TransactionTemplateComponent是我创建的模板类,下面是其内容1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33package com.ll.blog.transaction;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
* 公共事务模板组件
* @author leon
* @since 2019/7/11 14:35
*/
public class TransactionTemplateComponent{
private TransactionTemplate transactionTemplate;
public TransactionTemplateComponent(TransactionTemplate transactionTemplate){
this.transactionTemplate = transactionTemplate;
}
public Object doTransactionWithResult(TransactionHandler handler){
final Object result = new Object();
return transactionTemplate.execute(new TransactionCallback() {
@Override
public Object doInTransaction(TransactionStatus status){
try {
return handler.transactionContent();
} catch (Exception ex) {
status.setRollbackOnly();
return result;
}
}
});
}
}
这个类就一个方法doTransactionWithResult,返回类型是Object,当然我们可以定义任意的放回类型。一般在web工程中,我们会返回一个自定义的类型。其中TransactionHandler是我定义的事务处理类,其内容如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15package com.ll.blog.transaction;
* 事务接口
* @author leon
* @since 2019/7/11 14:37
*/
public interface TransactionHandler{
* 需要执行事务处理的代码放置在此方法中
* @return
* @throws Exception
*/
Object transactionContent() throws Exception;
}
从代码中可以看到,我们把需要事务处理的代码放置在transactionContent方法中即可。这里的放回类型是Object,我们可以自定义返回类型。
以上就完成了事务模板的编写。
那我们怎么使用呢?
使用
在代码中使用如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19@RestController
public class TransactionExample{
@Autowired
private TransactionTemplateComponent transactionTemplateComponent;
@RequestMapping(value = "/example" , method=RequestMethod.POST)
public String example(HttpServletRequest request, Map inputData){
// 事务
Object result = transactionTemplateComponent.doTransactionWithResult(new TransactionHandler() {
@Override
public Object transactionContent() throws Exception{
// 这里面写逻辑
Object re = new Object;
return re;
}
});
return "";
}
}
上面代码展示了如何对需要采用事务处理的逻辑进行编写。首先注入transactionTemplateComponent,然后实现TransactionHandler匿名类,在其transactionContent方法中编写具体的业务逻辑。
Spring 中声明式事务管理