写的有点乱,对不起了。其中dos窗口操作是1和2有先后顺序的,我没有进行说明,这里会看的很乱。对不起!
什么是事务
事务(TRANSACTION)是作为单个逻辑工作单元执行的一系列操作。
这些操作作为一个整体一起向系统提交,要么都执行,要么都不执行。
事务是一个不可分割的工作逻辑单元。
例如:银行转账过程就是一个事务。它需要两条update语句来完成,这两条语句是一个整体,如果其中一条出现错误,则整个转账业务也应取消,两个账户中的余额应恢复到原来的数据。
事务的特性
事务必须具备以下四个属性,简称ACID属性:
原子性(Atomicity):事务是一个完整的操作。事务的各步操作是不可分的(原子的);要么都执行,要么都不执行
一致性(Consistency):当事务完成时,数据必须处于一致状态
一致性中有个名词叫做一致读。
一致读:consistent read,意思是你哪时开始操作的数据,不管过了多长时间读取到,操作都是你开始时间时的数据。
解释:在10:00时一个用户进行了查询操作:
select * from scott.student where sno=4;
而student表中的数据非常大,到10:30分才找到sno=4的student的信息。
但是如果在10:20分的时候,另一个用户修改了sno=4的student的信息:
update student set sage=54 where sno=4;commit;
那么此时,10:00用户查询到的信息是修改前的信息。
隔离性(Isolation):对数据进行修改额所有并发事务时彼此隔离的,这表明事务必须是独立的,它不应以任何方式依赖于或影响其他事物。
永久性(Durability):事务完成后,它对数据库的修改被永久保持,事务日志能够保持事务的永久性。
oracle11g事务的命令
Sql Server中使用下列语句来管理事务:
开始事务:begin transaction
提交事务:commit transaction
回滚(撤销)事务:ROLLBACK TRANSACTION
Oracle11g中事务相关的命令:commit、savepoint、rollback
Sql*plus中,设置是否自动提交:set autocommit on|off。
一般在操作完成后要关闭自动提交
事务的相关操作:
dos窗口操作:
sqlplus scott/cloudar@orcl
create table student(sno int,sname varchar2(10),sage int);
insert into student values(1,'Tom',21);
insert into student values(2,'Bob',22);
insert into student values(3,'John',23);
insert into student values(4,'Mike',24);
commit;
clear;
select * from student;
// 一致性操作:
update student set sage = 34 where sno=4;
commit;
// 隔离性
update student set sage=11 where sno=1;// 暂时不进行提交,在dos窗口2进行修改操作:
rollback;
// 保存点
update student set sage = 33 where sno=3;
savepoint mark1; // 设置第一个保存点
delete student werhe sno=3;
savepoint mark2;// 设置第二个保存点
insert into student values(3,'C',3);
savepoint mark3;// 设置第三个保存点
select * from student;
delete student where sno=3;
select * from student;
// 现在想撤销删除操作,即回退到mark3的保存点
rollback to savepoint mark3;// 删除操作就会被回滚。
// 进行更新、插入操作也就可以根据savepoint来进行回滚操作了。
第二个dos窗口:
sqlplus system/sys@orcl;
select * from scott.student wehre sno=4;
// 启用用户
conn / as sysdba;
alter user hr identified by hr account unlock;// 修改密码和解锁。
grant connect to hr;
gramt se;ect any table to hr;
select * from scott.student where sno=4;
// 不同用户下查看的数据是一致的,这就是一致性的含义。
// 在窗口1进行update操作而未提交时,也进行修改操作:
update student set sage=111 where sno=1;// 此时会进入等待状态。
// 在窗口1rollback后就会继续执行了。
commit;
JAVA中进行oracle11g的事务处理
1 默认是自动提交。
2 开启事务使用setAutoCommit(false),这样可以避免自动提交。
3 通过Savepoint接口来声明保存点。
事务处理的例子:
题目1:
create table yggz(code int,salary number(7,2));
insert into yggz values(1,1000);
insert into yggz values(2,150);
commit;
完成任务:
如果1号员工的salary多于300源,则从一号员工salary中减少300源,同时加到2号员工的salary上。
实现:
题目2:
create table yggz(code int, salary number(7,2));
insert into yggz values(1, 1000);
insert into yggz values(2, 150);
commit;
完成任务:
如果1号员工的salary多于300元,则从1号员工的salary中减少300元,同时加到2号员工的salary上,但是还要确保转账后的1号员工的salary多于转账后的2号员工的salary。
package com.oaj;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.sql.Statement;
public class TestTransaction {
String driver = "oracle.jdbc.driver.OracleDriver";
String strUrl = "jdbc:oracle:thin:@localhost:1521:ORCL";
Statement stmt = null;
PreparedStatement ps = null;
ResultSet rs = null;
Connection conn = null;
float salary = 0f;
float salary2 = 0f;
String sqlStr = null;
public static void main(String[] args) {
new TestTransaction().test1();
}
// 题目1
public void test1(){
try {
Class.forName(driver);
conn = DriverManager.getConnection(strUrl,"scott","cloudar");
conn.setAutoCommit(false);
// 得到一号员工的salary
sqlStr = "select salary from ygzz where code=1";
ps = conn.prepareStatement(sqlStr);
rs = ps.executeQuery();
while(rs.next()){
salary = rs.getFloat(1);
}
if(salary < 300){
throw new RuntimeException("小于300,不可转账");
}
sqlStr = "update yggz set salary = salary - 300 where code=1";
ps = conn.prepareStatement(sqlStr);
ps.executeUpdate();
sqlStr = "update yggz set salary = salary + 300 where code=2";
ps = conn.prepareStatement(sqlStr);
ps.executeUpdate();
// 如果未有执行SQLException,则执行commit操作
conn.commit();
System.out.println("执行成功了");
} catch(SQLException se){
if(conn!=null){
try {
conn.rollback();
System.out.println("失败了");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
try{
if(rs !=null){
rs.close();
}
if(ps!=null){
ps.close();
}
if(conn!=null){
conn.close();
}
} catch(Exception e){
e.printStackTrace();
}
}
}
// 题目2
public void test2(){
try {
Class.forName(driver);
conn = DriverManager.getConnection(strUrl,"scott","cloudar");
conn.setAutoCommit(false);
// 得到一号员工的salary
sqlStr = "select salary from ygzz where code=1";
ps = conn.prepareStatement(sqlStr);
rs = ps.executeQuery();
while(rs.next()){
salary = rs.getFloat(1);
}
if(salary < 300){
throw new RuntimeException("小于300,不可转账");
}
// 设置保存点
Savepoint point1 = conn.setSavepoint("point1");
sqlStr = "update yggz set salary = salary - 300 where code=1";
ps = conn.prepareStatement(sqlStr);
ps.executeUpdate();
sqlStr = "update yggz set salary = salary + 300 where code=2";
ps = conn.prepareStatement(sqlStr);
ps.executeUpdate();
// 得到1号员工的工资
sqlStr = "select salary from yggz where cdoe=1";
ps = conn.prepareStatement(sqlStr);
rs = ps.executeQuery();
while(rs.next()){
salary = rs.getFloat(1);
}
// 得到2号员工的工资
sqlStr = "select salary from yggz where code=2";
ps = conn.prepareStatement(sqlStr);
rs = ps.executeQuery();
while(rs.next()){
salary2 = rs.getFloat(1);
}
if(salary > salary2){
conn.rollback(point1);
System.out.println("没有转账成功");
}else{
System.out.println("转账成功");
}
// 如果未有执行SQLException,则执行commit操作
conn.commit();
System.out.println("执行成功了");
} catch(SQLException se){
if(conn!=null){
try {
conn.rollback();
System.out.println("失败了");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
try{
if(rs !=null){
rs.close();
}
if(ps!=null){
ps.close();
}
if(conn!=null){
conn.close();
}
} catch(Exception e){
e.printStackTrace();
}
}
}
}
java操作oracle数据库的代码中的表在dos窗口1操作记录那就有进行创建的,希望对大家有帮助。如果不好还请指点,谢谢!