spring 事务
2022-04-22 16:02:59 0 举报
AI智能生成
登录查看完整内容
spring 事务
作者其他创作
大纲/内容
原子性(Atomicity)
一致性(Consistency)
隔离性(Isolation)
持久性(Durability)
属性
Read uncommitted(未授权读取、读未提交)
Read committed(授权读取、读提交)
Repeatable read(可重复读取)【mysq默认】
Serializable(序列化)
隔离级别
事务
事务执行时间过长
事务A和事务B在操作同一条记录
事务的死锁
代码例子
TransactionDefinition def = new DefaultTransactionDefinition(); TransactionStatus status = transactionManager.getTransaction(def); try { // 事务操作 // 事务提交 transactionManager.commit(status); } catch (DataAccessException e) { // 事务提交 transactionManager.rollback(status); throw e; }
基于底层的API,如PlatformTransactionManager、TransactionDefinition 和 TransactionTemplate
编程式事务方式需要是开发者在代码中手动的管理事务的开启、提交、回滚等操作
编程式事务
Spring默认的事务传播类型如果当前没有事务,则自己新建一个事务,如果当前存在事务,则加入这个事务
REQUIRED
当前存在事务,则加入当前事务,如果当前没有事务,就以非事务方法执行
SUPPORTS
当前存在事务,则加入当前事务,如果当前事务不存在,则抛出异常。
MANDATORY
创建一个新事务,如果存在当前事务,则挂起该事务。
REQUIRES_NEW
NOT_SUPPORTED
不使用事务,如果当前事务存在,则抛出异常
NEVER
如果当前事务存在,则在嵌套事务中执行,否则REQUIRED的操作一样(开启一个事务)
NESTED
事务的传播
@Transactional
声明式事务管理方法允许开发者配置的帮助下来管理事务,而不需要依赖底层API进行硬编码。开发者可以只使用注解或基于配置的 XML 来管理事务。
对代码没有侵入性,方法内只需要写业务逻辑就可以了。
优点
这些操作自身是无法回滚的,这就会导致数据的不一致。可能RPC调用成功了,但是本地事务回滚了,可是PRC调用无法回滚了。
在事务中有远程调用,就会拉长整个事务。那么久会导致本事务的数据库连接一直被占用,那么如果类似操作过多,就会导致数据库连接池耗尽。
如果开发者没有注意到一个方法是被事务嵌套的,那么就可能会再方法中加入一些如RPC远程调用、消息发送、缓存更新、文件写入等操作
@Transactional 注解属性 propagation 设置错误
@Transactional 注解属性 rollbackFor 设置错误
@Servicepublic class UserService { @Autowired private UserMapper userMapper; public void add(UserModel userModel) { userMapper.insertUser(userModel); updateStatus(userModel); } @Transactional public void updateStatus(UserModel userModel) { doSameThing(); }}
错误例子
解决1:只需要新加一个Service方法,把@Transactional注解加到新Service方法上
解决2:Service类中注入自己
@Servciepublic class ServiceA { public void save(User user) { queryData1(); queryData2(); ((ServiceA)AopContext.currentProxy()).doSave(user); } @Transactional(rollbackFor=Exception.class) public void doSave(User user) { addData1(); updateData2(); } }
解决3:
同一个类中方法调用,导致@Transactional失效
因为spring事务,默认情况下只会回滚RuntimeException(运行时异常)和Error(错误),对于普通的Exception(非运行时异常),它不会回滚。
异常被catch捕获导致@Transactional失效
数据库引擎不支持事务
(类本身) 未被spring管理
@Slf4j@Servicepublic class UserService { @Autowired private UserMapper userMapper; @Autowired private RoleService roleService; @Transactional public void add(UserModel userModel) throws Exception { userMapper.insertUser(userModel); new Thread(() -> { roleService.doOtherThing(); }).start(); }}@Servicepublic class RoleService { @Transactional public void doOtherThing() { System.out.println(\"保存role表数据\"); }}
多线程调用
声明式事务用不对容易失效
缺点
声明式事务
事务管理机制
spring 事务
0 条评论
回复 删除
下一页