JDBC基础学习笔记_04_jdbc事务处理
2015-11-03 17:05
676 查看
一.什么是事务呢?
事务是并发控制的基本单位,如果在同一时间由多个用户同时对数据库进行操作,数据库数据会紊乱,我们要对这种并发行为,进行控制。
举个例子: 银行的转账功能,出账和进账,要么都执行,要么都不执行,我们将其看成一个事务。
我们编程时,可以将事务看成一组sql语句,其结果作为一个整体永久的修改数据库,或者同时放弃对数据库的修改。
二.事务的四个特征:
1. 原子性: 事务中包含的操作都被看做是一个逻辑单元,这个逻辑单元中的操作要么全部成功,要么全部失败。
2.一致性: 事务开始之前,事务结束之后,数据库都处于一致性状态,完整性约束没有破坏。
3. 隔离性: 事务之间是独立的,一个事务不能影响其他事务。
4. 持久性: 事务完成之后,对系统影响是永久的,对数据库的操作结果也是永久的。
三. 事务的sql语句
1.开始事务 : BEGIN TRANSACTION
2. 提交事务 : COMMIT TRANSACTION
3. 回滚事务: ROLLBACK TRANSACTION
四. 我们做一个错误的实例,之前我们有两张表,一张用户表,一张地址表,我们用两个方法将maik这个人,插入到两个表中,在地址表中制造异常信息。
我们看到user表更改了,但是对应的地址表没有更改,数据不一致,这是个很严重的问题,我们应该运用事务来解决它,即地址表不能更改的话,user表也不能改!
五. 我们在四的基础上修改代码,代码如下:
先放上关于Connection.setAutoCommit的使用:http://blog.csdn.net/xiayimiaokuaile/article/details/6422032
(设定setAutoCommit(false)没有在catch中进行Connection的rollBack操作,操作的表就会被锁住,造成数据库死锁):
代码中的方法都进行了修改:
我们看到,并没有插入数据,事务功能成功~~~记得之前说的注意,一定要在catch中回滚。!!!
事务是并发控制的基本单位,如果在同一时间由多个用户同时对数据库进行操作,数据库数据会紊乱,我们要对这种并发行为,进行控制。
举个例子: 银行的转账功能,出账和进账,要么都执行,要么都不执行,我们将其看成一个事务。
我们编程时,可以将事务看成一组sql语句,其结果作为一个整体永久的修改数据库,或者同时放弃对数据库的修改。
二.事务的四个特征:
1. 原子性: 事务中包含的操作都被看做是一个逻辑单元,这个逻辑单元中的操作要么全部成功,要么全部失败。
2.一致性: 事务开始之前,事务结束之后,数据库都处于一致性状态,完整性约束没有破坏。
3. 隔离性: 事务之间是独立的,一个事务不能影响其他事务。
4. 持久性: 事务完成之后,对系统影响是永久的,对数据库的操作结果也是永久的。
三. 事务的sql语句
1.开始事务 : BEGIN TRANSACTION
2. 提交事务 : COMMIT TRANSACTION
3. 回滚事务: ROLLBACK TRANSACTION
四. 我们做一个错误的实例,之前我们有两张表,一张用户表,一张地址表,我们用两个方法将maik这个人,插入到两个表中,在地址表中制造异常信息。
package com.langzimingjian.com; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; public class TransactionTest { /** * 连接数据库,返回Connection对象 * @return 返回的Connection对象 */ public static Connection getConnection(){ Connection connection = null; try { Class.forName("com.mysql.jdbc.Driver"); connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jsp_bd","root", ""); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return connection; } /** * 向用户表插入数据 */ public static void insertUserTable(){ Connection coneConnection = getConnection(); String insertString = "insert into tbl_user(id,name,password,email) values(?,?,?,?)"; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { preparedStatement = coneConnection.prepareStatement(insertString); preparedStatement.setInt(1,20); preparedStatement.setString(2,"maik"); preparedStatement.setString(3,"12345678910"); preparedStatement.setString(4,"maik@qq.com"); int count = preparedStatement.executeUpdate(); System.out.println("成功插入" + count + "条数据"); } catch (Exception e) { e.printStackTrace(); }finally{ try { if(coneConnection != null){ coneConnection.close(); } if(preparedStatement!= null){ preparedStatement.close(); } if(resultSet!= null){ resultSet.close(); } } catch (Exception e2) { // TODO: handle exception } } } /** * 向地址表中插入数据 */ public static void insertAddressTable(){ Connection connection = getConnection(); PreparedStatement preparedStatement = null; try { String insertString = "insert into tbl_address(id,city,country,user_id)values(?,?,?,?)"; preparedStatement = connection.prepareStatement(insertString); /* 因为地址表中已经有主键为1了,所以插入地址表的时候会抛出异常*/ preparedStatement.setInt(1, 1); preparedStatement.setString(2, "三亚"); preparedStatement.setString(3, "中国"); preparedStatement.setInt(4, 20); int count = preparedStatement.executeUpdate(); System.out.println("成功插入" + count + "条语句到地址表"); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); }finally{ try { if(connection != null){connection.close();} if(preparedStatement != null){preparedStatement.close();} } catch (Exception e2) { // TODO: handle exception e2.printStackTrace(); } } } public static void main(String[] args) { insertUserTable(); insertAddressTable(); } }注意第七十行。运行结果
我们看到user表更改了,但是对应的地址表没有更改,数据不一致,这是个很严重的问题,我们应该运用事务来解决它,即地址表不能更改的话,user表也不能改!
五. 我们在四的基础上修改代码,代码如下:
先放上关于Connection.setAutoCommit的使用:http://blog.csdn.net/xiayimiaokuaile/article/details/6422032
(设定setAutoCommit(false)没有在catch中进行Connection的rollBack操作,操作的表就会被锁住,造成数据库死锁):
代码中的方法都进行了修改:
package com.langzimingjian.com; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; public class TransactionTest { /** * 连接数据库,返回Connection对象 * @return 返回的Connection对象 */ public static Connection getConnection(){ Connection connection = null; try { Class.forName("com.mysql.jdbc.Driver"); connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jsp_bd","root", ""); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return connection; } /** * 向用户表插入数据 */ public static void insertUserTable(Connection coneConnection) throws Exception{ String insertString = "insert into tbl_user(id,name,password,email) values(?,?,?,?)"; PreparedStatement preparedStatement = null; preparedStatement = coneConnection.prepareStatement(insertString); preparedStatement.setInt(1,20); preparedStatement.setString(2,"maik"); preparedStatement.setString(3,"12345678910"); preparedStatement.setString(4,"maik@qq.com"); int count = preparedStatement.executeUpdate(); System.out.println("成功插入" + count + "条数据"); } /** * 向地址表中插入数据 */ public static void insertAddressTable(Connection connection) throws Exception{ PreparedStatement preparedStatement = null; String insertString = "insert into tbl_address(id,city,country,user_id)values(?,?,?,?)"; preparedStatement = connection.prepareStatement(insertString); /* 因为地址表中已经有主键为1了,所以插入地址表的时候会抛出异常*/ preparedStatement.setInt(1, 1); preparedStatement.setString(2, "三亚"); preparedStatement.setString(3, "中国"); preparedStatement.setInt(4, 20); int count = preparedStatement.executeUpdate(); System.out.println("成功插入" + count + "条语句到地址表"); } public static void main(String[] args) { Connection connection = null; try { connection = getConnection(); //在這裡設置為false,如果下面對表操作出現異常,最終不會修改數據庫 connection.setAutoCommit(false); insertUserTable(connection); insertAddressTable(connection); //提交事務 connection.commit(); } catch (Exception e) { // TODO Auto-generated catch block System.out.println("======捕捉到sql異常====="); e.printStackTrace(); try { //這裡是重點:(设定setAutoCommit(false)没有在catch中进行Connection的rollBack操作,操作的表就会被锁住,造成数据库死锁): connection.rollback(); } catch (Exception e2) { // TODO: handle exception e2.printStackTrace(); }finally{ try { if(connection!= null){connection.close();} } catch (Exception e3) { // TODO: handle exception e3.printStackTrace(); } } } } }运行结果:
我们看到,并没有插入数据,事务功能成功~~~记得之前说的注意,一定要在catch中回滚。!!!
相关文章推荐
- redis入门笔记(2)
- ThinkPHP使用技巧经验总结
- android教程学习第十讲:启动脚本init.rc的学习
- 渗透测试学习系列之《Metasploitable介绍》(一)
- 习题2-4 字序列的和 解题报告
- Mysql忘记密码
- 图解如何用打印机套打快递单
- 【jQuery】遮罩效果的实现
- Building fw printenv and fw setenv
- redis入门笔记(1)
- Android 启动过程简析
- Newtonsoft.Json 将C#对象转化为json格式
- 网络TCP/UDP编程学习
- tabelayout,GridLayout的一些基础属性
- EAS BOS手动写的保存方法
- android中进行https连接的方式
- SetEvent与PulseEvent的区别
- HTTP 的get方法
- Centos7 安装python3的独立环境
- Web Service单元测试工具实例介绍之SoapUI