1.什么是事务?
事务(Transaction),一般是指要做的或所做的事情。
在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。
程序执行单元(unit)---数据库操作的一组SQL语句的执行。
1.由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写
2.由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。
例如:我们要实现一个银行转账的操作,首先从A账户减掉指定的金额,然后B账户增加指定的金额,此时转账操作结束。上面的操作如果对应成数据库操作,那么就需要执行两条update语句。数据库把这两条update语句的执行就是一个事务。
事务--指访问并可能更新数据库中各种数据项的一组SQL语句的执行单元(unit)。
2数据库的事务有4大特征【ACID】
1.--原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做。
2.--一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
3.--隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
4.--持久性(durability)。持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
3.java中事务的隔离级别
在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别。
JDBC定义了五种事务隔离级别:
TRANSACTION_READ_UNCOMMITTED 允许脏读、不可重复读和幻读。
TRANSACTION_READ_COMMITTED 禁止脏读,但允许不可重复读和幻读。
TRANSACTION_REPEATABLE_READ 禁止脏读和不可重复读,单运行幻读。
TRANSACTION_SERIALIZABLE 禁止脏读、不可重复读和幻读。
TRANSACTION_NONE JDBC驱动不支持事务
4.JDBC的事务管理操作
JDBC的事务管理操作需要通过java.sql.Connection接口来设置的。
事务的隔离级别
static int |
TRANSACTION_NONE 指示不支持事务的常量。 |
static int |
TRANSACTION_READ_COMMITTED 一个常数表示防止脏读; 可能会发生不可重复的读取和幻像读取。 |
static int |
TRANSACTION_READ_UNCOMMITTED 一个常量表示可能会发生脏读,不可重复读和幻读。 |
static int |
TRANSACTION_REPEATABLE_READ 一个常量表示防止了脏读和不可重复读; 可以发生幻读。 |
static int |
TRANSACTION_SERIALIZABLE 一个常数表示防止脏读,不可重复读和幻影读。 |
也可以使用数字[Value]
Modifier and Type |
Constant Field |
Value |
0 |
||
2 |
||
1 |
||
4 |
||
8 |
设置事务隔离级别的方法
void |
setTransactionIsolation(int level) 尝试将此 Connection对象的事务隔离级别更改为给定的对象。 |
例如:
Connection接口对象.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
Connection接口对象.setTransactionIsolation(8);
设置是否自动提交事务方法【默认JDBC事务是自动提交的】
void |
setAutoCommit(boolean autoCommit) 将此连接的自动提交模式设置为给定状态。 |
Connection接口对象.setAutoCommit(false) ; 设置为手动提交事务。
事务的提交方法
void |
commit() 使自上次提交/回滚以来所做的所有更改都将永久性,并释放此 Connection对象当前持有的任何数据库锁。 |
事务的回滚方法【异常中执行】
void |
rollback() 撤消在当前事务中所做的所有更改,并释放此 Connection对象当前持有的任何数据库锁。 |
建立数据库连接
package com.wangxing.jdbcdemo2.shiwu;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* 数据库驱动管理类--加载数据库驱动,得到数据库连接
* @author Administrator
*
*/
public class DBConnection {
//定义数据库驱动名称
private static final String DRIVERNAME="com.mysql.jdbc.Driver";
//定义数据库的url
//【jdbc:mysql://数据库服务器IP:端口号/数据库名称】
private static final String URL="jdbc:mysql://127.0.0.1:3306/test";
//定义数据库登录名
private static final String USERNAME="root";
//定义数据库登录密码
private static final String PASSWORD="200120";
//加载数据库驱动
static{
try {
Class.forName(DRIVERNAME);
} catch (ClassNotFoundException e) {
System.out.println("数据库加载失败");
e.printStackTrace();
}
}
/**
* 得到数据库连接对象
*/
public static Connection getConnection(){
Connection conn=null;
try {
conn=DriverManager.getConnection(URL, USERNAME, PASSWORD);
} catch (SQLException e) {
System.out.println("获取数据库连接失败");
e.printStackTrace();
}
return conn;
}
}
转账的具体操作
package com.wangxing.jdbcdemo3.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import com.wangxing.jdbcdemo3.db.DBConnection;
/**
* 转账操作类
*
* @author Administrator
*
*/
public class ZhuanZhangObject {
public void zhuanzhuang() {
Connection conn = null;
PreparedStatement statement = null;
try {
// 得到数据库连接
conn = DBConnection.getMyConnection();
// 设置为手动提交事务
conn.setAutoCommit(false);
// 设置事务的隔离级别
conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
// 创建转账的sql语句
String zhuanzhangsql = "update t_zhanghu set zhuanghu_jine=? where zhuanghu_name=?;";
statement = conn.prepareStatement(zhuanzhangsql);
statement.setInt(1, 9000);
statement.setString(2, "zhangsan");
statement.executeUpdate();
int a = 10 / 0;
statement.setInt(1, 11000);
statement.setString(2, "lisi");
statement.executeUpdate();
// 提交事务
conn.commit();
} catch (Exception e) {
System.out.println("转账失败");
// 回滚事务
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
} finally {
if (statement != null && conn != null) {
try {
statement.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
测试方法
package com.wangxing.jdbcdemo2.shiwu;
public class TestMain {
public static void main(String a[]){
ZhuanZhangPbject zz=new ZhuanZhangPbject();
zz.zhuanzhang();
}
}
总结:
- SQL语句执行的connection[数据库连接对象]与事务设置的connection[数据库连接对象]对象要相同。
- 开始事务conn.setAutoCommit(false);
- 设置事务的隔离级别
//connection数据库连接对象
connection.setTransactionIsolation(Connection.TRANSACTION_NONE);
connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
connection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
connection.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
connection.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
- 提交事务conn.commit();
- 设置事务回滚【异常中进行】conn.rollback();
上面我们所操作的事务管理是编码式事务管理,后面我们在学习Spring框架的时候会学习到声明式事务管理。