oracle11g中的事务

写的有点乱,对不起了。其中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操作记录那就有进行创建的,希望对大家有帮助。如果不好还请指点,谢谢!

扫描二维码关注公众号,回复: 4055960 查看本文章

猜你喜欢

转载自blog.csdn.net/zuoyouzouzou/article/details/83957339