1 概述
- 数据库事务是由一组逻辑上相互依赖的SQL语句组成,它具有ACID特征。
- 数据库管理系统采用日志来保证事务的原子性、一致性和持久化性,采用锁机制来实现事务的隔离性。
数据库系统支持两种事务模式:
- 自动提交模式:每个SQL语句就是一个独立的事务,当数据库系统执行完一个SQL后,自动提交事务;
- 手工提交事务:由数据库的应用程序显示指定事务的开始边界和结束边界。
注意:Mysql的INNODB和BDB类型的表支持事务,而MyISAM类型的表不支持事务。下面两段内容引用:http://blog.csdn.net/ocean1010/article/details/6908064
MyISAM:这个是默认类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法.与其他存储引擎比较,MyISAM具有检查和修复表格的大多数工具. MyISAM表格可以被压缩,而且它们支持全文搜索.它们不是事务安全的,而且也不支持外键。如果事物回滚将造成不完全回滚,不具有原子性。如果执行大量的SELECT,MyISAM是更好的选择。
InnoDB:这种类型是事务安全的.它与BDB类型具有相同的特性,它们还支持外键.InnoDB表格速度很快.具有比BDB还丰富的特性,因此如果需要一个事务安全的存储引擎,建议使用它.如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。
2 声明事务的方式
图2-1 以MySQL数据库为例展示了数据库声明事务的方式:
由此可知声明事务有四种方式:
图2-1 数据库声明事务的方式
- 通过mysql.exe
- 通过JDBC API
- 通过JTA API,支持分布式事务
- 通过Hibernate API
2.1在mysql.exe中声明事务
每个数据库连接都有一个全局变量@@autocommit,表示当前的事务模式,其值:
- 0:手工模式,必须begin、commit、rollback显示指定事务的边界。
- 1:自动提交(默认值),一条语句就是一个独立的事务。
可以使用一下的SQL命令查看和设置autocommit:
2.2Java应用通过JDBC API声明事务
java.sql.Connection类代表一个数据库连接,默认采用自动提交模式。其中的控制事务的方法:
- setAutoCommit(boolean autoCommit)
- commit()
- rollback()
缺点:使得java应用程序与JDBC API绑定,削弱java应用的独立性。
2.3Java应用通过Hibernate API声明事务
Hibernate API封装了JDBC API和JTA API(相关的介绍我以后会补上),优点:
- 利于跨平台
- 事务与Session集成的更加紧密
声明事务的过程:
Session session = sessionFactory.openSessin();//获得Session实例
Transaction tx; //声明事务
try {
tx = session.beginTransaction(); //开始事务:该方法为Session分配数据库连接并自动把连接设置成手工提交事务模式,然后开始一个事务。
//执行一些操作
...
tx.commit();//提交事务:先调用Session的flush()方法清理缓存,同步更新数据库,向数据库提交事务,释放Session占用的数据库连接。
} catch(RuntimeException e) { //Hibernate抛出运行时异常,是受检查型异常
if(tx != null) {
tx.rollback();//事务回滚
}
} finally {
session.close();
}
说明:session与一个数据库事务绑定时(session
.beginTransactin()方法被调用时)才占用数据库连接,这可以缩短Session占用数据库资源的时间,以提高程序性能。
Session与事务的关系:
- 及时提交或撤销事务——及时释放事务占用的数据库资源,提高数据库运行性能。
- 一个Session对应多个事务——可以重用Session缓存中的持久化对象,但一个Session只允许有一个为提交的事务。
- 放弃出现异常的Session——避免出现不一致数据的可能
- 自动提交事务模式——一般很少用,最好显示声明。