1.事务基本概念
-
什么是事务
数据库事务通常是指对数据库进行读或写的一个操作过程。有两个目的,第一个是为数据库操作提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法;第二个是当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰
-
事务的特性(ACID)
-
原子性(Atomicity):事务必须是原子工作单元,一个事务中的所有语句应该做到,要么全部成功,要么全部失败
-
一致性(Consistency):让数据保持逻辑上的“合理性”,比如:小明给小红打100元,就必须让小明账户减少100元,同时小红账户上增加100元
-
隔离性(Isolation):如果多个事务同时并发执行,但每个事务就像各自独立执行一样
-
持久性(Durability):一个事务执行成功,则对数据来说应该是一个明确的硬盘数据更改(而不仅仅是内存中的变化)
-
要使用事务的话,表的引擎要为innodb引擎
2.事务传播行为
-
如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务方法的执行行为
-
@Transactional(propagation = Propagation.REQUIRED) 如果有事务那么加入事务,没有的话新建一个(默认)
-
@Transactional(propagation = Propagation.SUPPORTS) 如果其他bean调用这个方法,在其他bean中声明事务,那就用事务;如果其他bean没有声明事务那就不用事务
-
@Transactional(propagation = Propagation.MANDATORY) 必须在一个已有的事务中执行,否则抛出异常
-
@Transactional(propagation = Propagation.REQUIRES_NEW) 不管是否存在事务,都创建一个新的事务,原来的挂起,新的事务执行完毕继续执行老的事务
-
@Transactional(propagation = Propagation.NOT_SUPPORTED) 不为这个方法开启事务
-
@Transactional(propagation = Propagation.NEVER) 必须在一个没有的事务中执行,否则抛出异常(与propagation = Propagation.MANDATORY相反)
-
@Transactional(propagation = Propagation.NESTED) 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于propagation = Propagation.REQUIRED
-
3.事务隔离级别
-
事务隔离级别:是指若干个并发的事务之间的隔离程度
-
@Transactional(isolation = Isolation.READ_UNCOMMITTED) 读取未提交数据(会出现脏读、不可重复读)基本不使用
-
@Transactional(isolation = Isolation.READ_COMMITTED) 读取已提交数据(会出现不可重复读和幻读)
-
@Transactional(isolation = Isolation.REPEATABLE_READ) 可重复读(会出现幻读)
-
@Transactional(isolation = Isolation.SERIALIZABLE) 串行化
-
-
MySQL:默认为REPEATABLE_READ级别
4.事务开启关闭
-
事务的开启与提交
-
事务的开启:begin;start transaction;
-
事务的提交:commit;
-
事务的回滚:rollback;
-
开启autocommit(临时生效)
-
OFF(0):关闭
-
ON(1):开启
set autocommit = 0;
show variables like 'autocommit';
-
开启autocommit(永久生效):修改配置文件:vim /etc/my.cnf,在[mysqld]下面加上:autocommit=1,记得重启服务才会生效
5.Java代码事务使用
-
启动类加上@EnableTransactionManagement
-
业务类或者业务方法加上@Transactional