最近,在使用Hibernate进行项目开发,发现数据库事务方面的知识有些遗忘了。现在抽时间整理出来,和大家分享一下。
什么是事务(Transaction)?简单来说,事务是一个最小的、不可再分的工作单元。它通常对应一个完整的业务逻辑,需要批量的DML语句共同联合完成。例如在进行转账操作时,势必对应着A账户的减少且B账户的增加,而不可拆分为A账户的减少和B账户的增加。
事务有如下四个特征(ACID):
原子性:要求事务是最小的工作单元,不可再分
一致性:要求事务中的所有DML语句要么同时成功,要么同时失败
隔离性:要求事务之间相互透明,即在一个事务中无法看到其它事务
持久性:要求对于已提交事务,系统必须保证该事务对数据库的改变同步到数据库,持久性是事务终止的标志,是事务的保证
在事务进行过程中,未结束之前,DML语句不会更改数据库文件中的数据,只是在内存中完成这些操作。只有在事务结束且成功提交时才会修改数据库中的数据。
任何一条DML语句的执行,标志事务的开始,而事务结束的标志有两个,一个是commit,代表事务成功的结束;另一个是rollback,代表事务失败的结束。在MySQL中,事务默认是自动提交的,也就是说,任何一条DML语句都会开启并提交事务。
start transaction; 可以设置手动开启事务,并关闭自动提交
set autocommit=off; 关闭自动提交
set session autocommit=off; 关闭自动提交
事务的隔离级别:
1.读未提交:read uncommitted
事务A可以读到事务B尚未提交的数据,出现数据脏读现象。隔离级别最低,一般仅在理论中出现。
2.读已提交:read committed
事务A只能读到事务B已经提交的数据,避免了数据脏读,但是导致了不可重复读的发生。不可重复读是指事务A,B同时读取某一数据,事务B对其作了修改并提交,此时A就读不出和之前一致的数据了。读已提交是Oracle数据库默认的隔离级别。
3.可重复读:repeatable read
数据可以重复读取,但是出现了一个新问题,那就是幻读现象。何为幻读?幻读是指每次都从缓存中读数据,其数据可能与数据库中真实数据不一致。该隔离级别是MySQL默认的隔离级别。
4.不可并发:serializable
一个事务在操作数据库时,其它事务只能排队等待。该隔离级别安全性最高,但吞吐量太低,用户体验差,一般很少使用。