事务入门详解 _JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 事务入门详解

事务入门详解

 2011/11/14 6:40:04  coolxing  http://coolxing.iteye.com  我要评论(0)
  • 摘要:[coolxing按:转载请注明作者和出处,如有谬误,欢迎在评论中指正.]1.事务入门.事务是一组操作的集合,这些操作要么一起执行成功,要么一起执行失败.JDBC和Mysql数据的事务命令如下:Connection.setAutoCommit(false)---starttransactionConnection.rollback()-------------------rollbackConnection.commit()-------------------
  • 标签:

[coolxing按: 转载请注明作者和出处, 如有谬误, 欢迎在评论中指正.]?

?

1. 事务入门. 事务是一组操作的集合, 这些操作要么一起执行成功, 要么一起执行失败. JDBC和Mysql数据的事务命令如下:

Connection.setAutoCommit(false)---start transaction

Connection.rollback()-------------------rollback

Connection.commit()--------------------commit

Connection.setSavePoint()用于设置回滚点, 该方法返回一个SavePoint对象. 如果调用Connection.rollback(SavePoint sp)方法则回滚至sp锁代表的回滚点.

如果一个线程尚未开启事务, 则数据库将自动提交所有修改.?

线程开启事务之后, 执行了提交或者回滚时事务结束; 如果断开连接时事务既没有提交也没有回滚, 数据库将自动放弃所有修改(即自动回滚至事务开启处).

例子:

Java代码? javascripts/syntaxhighlighter/clipboard_new.swf">
  1. /*?
  2. ?*?create?table?transaction?(id?int?primary?key?auto_increment,?name?varchar(40),?money?float);?
  3. ?*?insert?into?transaction(name,?money)?values('coolxing',?5009.9);?
  4. ?*?insert?into?transaction(name,?money)?values('min',?6666.6);?
  5. ?*?insert?into?transaction(name,?money)?values('yong',?3333.1);?
  6. ?*/??
  7. public?class?DbTransaction?{??
  8. ????@Test??
  9. ????public?void?transactionWithNoexception()?{??
  10. ????????Connection?conn?=?null;??
  11. ????????PreparedStatement?st?=?null;??
  12. ??????????
  13. ????????try?{??
  14. ????????????conn?=?JdbcUtils.getConnection();??
  15. ????????????//?开启事务.?事务开启之后,?所有针对数据库的操作都需要进行提交,?否则在断开连接时服务器将自动回滚.??
  16. ????????????conn.setAutoCommit(false);??
  17. ??????????????
  18. ????????????String?sql?=?"update?transaction?set?money=money+1000?where?id=1";??
  19. ????????????st?=?conn.prepareStatement(sql);??
  20. ????????????st.executeUpdate();??
  21. ??????????????
  22. ????????????sql?=?"update?transaction?set?money=money-1000?where?id=2";??
  23. ????????????st?=?conn.prepareStatement(sql);??
  24. ????????????st.executeUpdate();??
  25. ??????????????
  26. ????????????sql?=?"select?*?from?transaction";??
  27. ????????????st?=?conn.prepareStatement(sql);??
  28. ????????????ResultSet?rs?=?st.executeQuery();??
  29. ????????????while(rs.next()?)?{??
  30. ????????????????System.out.println("--------------------");??
  31. ????????????????System.out.println(rs.getInt("id"));??
  32. ????????????????System.out.println(rs.getString("name"));??
  33. ????????????????System.out.println(rs.getFloat("money"));??
  34. ????????????}??
  35. ??????????????
  36. ????????????conn.commit();??
  37. ????????}?catch?(Exception?e)?{??
  38. ????????????e.printStackTrace();??
  39. ????????????if?(conn?!=?null)?{??
  40. ????????????????try?{??
  41. ????????????????????conn.rollback();??
  42. ????????????????}?catch?(SQLException?e1)?{??
  43. ????????????????????e1.printStackTrace();??
  44. ????????????????}??
  45. ????????????}??
  46. ????????}?finally?{??
  47. ????????????JdbcUtils.release(null,?st,?conn);??
  48. ????????}??
  49. ????}??
  50. }??

?

2. 事务的4大特性ACID.

a. 原子性(Atomicity): 事务是一个不可分割的执行单位, 事务中的操作要么全部成功, 要么全部失败.

b. 一致性(Consistency): 事务前后数据的完整性需要保持一致. 例如在一个转账事务中, 所有账户的总金额在事务执行前后必须相同.

c. 隔离性(Isolation): 事务的隔离性定义多个线程并发访问数据库时, 系统所采取的隔离措施. 详见后面的分析.

d. 持久性(Durability): 指事务一旦提交成功, 该事务对数据库中的数据所作的修改永久有效, 不可因外部意外情况对其有任何影响.

?

3. 事务的隔离性主要为了避免以下情况的发生:

a. 脏读. 指的是A事务读取了其他事务尚未提交的修改.

b. 不可重复读. 指的是A事务多次读取某行中的数据, 如果其他事务在A事务的读取间隔期间提交了对该行数据的修改, 而导致A事务多次读取的结果不同.

c. 虚读. 指的是A事务读取到了其他事务插入的数据.

?

4. 事务的隔离级别. sql标准定义了四种隔离级别:

a. read uncommitted: 最低级别, 无法避免脏读, 不可重复读, 虚读等情况的发生.

b. read committed: 可以避免脏读的发生, 但不能避免不可重复读和虚读的发生.

c. repeatable read: 可以避免脏读和不可重复读的发生, 但不能避免虚读的发生. 处于该级别的事务会对数据库中已有记录加锁, 使得其他事务无法提交对已有记录的修改, 但允许插入新的数据.

d. serializable: 可以避免以上所有情况的发生. 处于该级别的事务会对整个数据库加锁, 使得其他事务无法提交对该数据库的任何修改. 此时相当于单线程操作.

Mysql支持以上4种隔离级别, 其默认的隔离级别为repeatable read. set transaction isolation level语句可以更改当前事务的隔离级别, 如set transaction isolation level read committed语句将当前事务的隔离级别设置为read committed. select @@tx_isolation语句用于获取当前事务的隔离级别. 而Oracle只支持read committed和serializable级别.?

实际开发时, 需要根据项目需求选择不同的隔离级别. 尤其是不可重复读和虚读, 在某些应用场景下并非是需要避免的错误, 而是完全合法的.?

隔离级别越高, 数据库的性能就越差.

检验事务的隔离级别时, 需要创建多个"已开启事务"的线程.

?

  • 相关文章
发表评论
用户名: 匿名