JDBC例子4_事务管理

事务管理

1 事务概述
 事务指的是逻辑上的一组操作(多条sql语句),组成这组操作的各个单元要么全都成功,要么全都失败.
 事务作用:保证在一个事务中多次操作要么全都成功,要么全都失败.

例如转账:

update account set money=money-100 where name='tom';//tom转出100块
update account set money=money+100 where name='jerry';//jerry收到100块

以上两条sql语句,很明显是一组语句,因为转账要么都成功要么都失败,不应该出现一方成功另一方失败的情况.那么我们就需要把他们看成一个事务.

事务处理

事务处理:保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),要么整个事务回滚(rollback)到最初状态
当一个连接对象被创建时,默认情况下是自动提交事务:每次执行一个 SQL 语句时,如果执行成功,就会向数据库自动提交,而不能回滚。

事务开始于:
• 连接到数据库上,并执行一条DML语句(INSERT、UPDATE或DELETE)。
• 前一个事务结束后,又输入了另外一条DML语句。
事务结束于:
• 执行COMMIT或ROLLBACK语句。
• 执行一条DDL语句,例如CREATE TABLE语句;在这种情况下,会自动执行COMMIT语句。
• 执行一条DCL语句,例如GRANT语句;在这种情况下,会自动执行COMMIT语句。
• 断开与数据库的连接。
• 执行了一条DML语句,该语句却失败了;在这种情况中,会为这个无效的DML语句执行ROLLBACK语句。

事务特性
原子性:强调事务的不可分割.多条语句要么都成功,要么都失败。
一致性:强调的是事务的执行的前后,数据要保持一致.
隔离性:一个事务的执行不应该受到其他事务的干扰.
持久性:事务一旦结束(提交/回滚)数据就持久保持到了数据库.

2 使用JDBC原生的API进行事务管理

为了让多个 SQL 语句作为一个事务执行:
调用 Connection 对象的 setAutoCommit(false); 以取消自动提交事务
在所有的 SQL 语句都成功执行后,调用 commit(); 方法提交事务
在出现异常时,调用 rollback(); 方法回滚事务
若此时 Connection 没有被关闭, 则需要恢复其自动提交状态

#创建账号表
create table account(
	id int primary key auto_increment,
	name varchar(20),
	money double
);

package cn.njit.aff;
/****
 * 使用jdbc实现事务
 * 
 */
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Testjdbc {

	public static void main(String[] args) {
		Connection conn=getConnection();
		try {
			conn.setAutoCommit(false);
		} catch (SQLException e) {
			e.printStackTrace();
		}//设置成不自动提交
		
		String sql="Update account set money=money-? where name=?";
		PreparedStatement psmt;
	
		try {
			psmt=conn.prepareStatement(sql);
			psmt.setDouble(1, 500);
			psmt.setString(2, "螺纹");
			psmt.executeUpdate();
			System.out.println("----");
			//-------------------
			int x=1/0;
			//制造异常,引起回滚
			//-------------------
			
			sql="update account set money=money+? where name=?";
			psmt=conn.prepareStatement(sql);
			psmt.setDouble(1, 500);
			psmt.setString(2, "刘智伟");
			psmt.executeUpdate();
			System.out.println("----");
			
			conn.commit();

		} catch (SQLException e) {			
			try {
				System.out.println("======");
				e.printStackTrace();
				conn.rollback();
			}catch(SQLException e1) {
				e1.printStackTrace();
			}
		}finally {
			if(null!=conn) {
				try{
					conn.close();
				}catch (SQLException e2){
					e2.printStackTrace();
				}
			}
		}
	}
	
	public static Connection getConnection() {
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		String url="jdbc:mysql://localhost:3306/njit?useUnicode=true&characterEncoding=utf-8";
		String name="root";
		String password="admin";
		Connection conn = null;
		
		try {
			conn=DriverManager.getConnection(url, name, password);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		
		return conn;
		
	}
}

3 使用DBUtils实现事务管理

要点:

QueryRunner qr = new QueryRunner();//为了支持事务,不能传递连接池
conn = C3P0Utils02.getConnection(); //获取jdbc原生连接
conn.setAutoCommit(false); //开启事务
conn.commit(); //正常,则提交事务
conn.rollback(); //异常或者业务不正确,则回滚
Conn.close(); //最后关闭事务


package cn.njit.aff;
/****
 * 使用DBUtils实现事务
 */
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import util.C3P0Utils;

public class TestDBUtils {

	public static void main(String[] args) {
		testUpdate();
	}

	static void testUpdate() {
		QueryRunner qr = new QueryRunner();
		// 不能直接把conn放进去
		Connection conn = null;
		try {
			conn = C3P0Utils.getConnection();
			System.out.println("0");
		} catch (SQLException e) {
			e.printStackTrace();
		}
		try {
			conn.setAutoCommit(false);
			String sql = "Update account set money=money-? where name=?";
			Object[] o = { 500, "刘智伟" };
			qr.update(conn, sql, o);
			System.out.println("1");
			// ---------------
			int x=1/0;
			// ---------------
			String str = "update account set money=money+? where name=?";
			Object[] o2 = { 500, "螺纹" };
			qr.update(conn, str, o2);
			System.out.println("2");
			
			conn.commit();
		} catch (SQLException e) {
			try {
				System.out.println("===========");
				conn.rollback();
				e.printStackTrace();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
		} finally {
			try {
				if (null != conn) {
					conn.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

	}

}

猜你喜欢

转载自blog.csdn.net/AirTrioa/article/details/83116874