SQL> select salary from employees;
SALARY ---------- 3300 4300 4100 4300 3200 3000
6 rows selected.
·251·
2)为所有员工的工资数目增加100
SQL> update employees set salary = salary + 100;
6 rows updated.
3)执行回滚
SQL> rollback;
Rollback complete.
4)查看此时的工资信息
SQL> select salary from employees;
SALARY ---------- 3300 4300 4100 4300 3200 3000
6 rows selected.
5)事实上,一旦执行了rollback命令,就代表了一个事务的结束。回滚操作之后,所有的数据均为发生改变。
2.利用update语句更新表employees中的salary,为所有员工的工资数目增加100,然后利用save point保存标记点。接着为所有员工的工资数目增加200,然后利用rollback to savepoint回滚至标记点,最后利用commit提交数据修改。查看此时的工资状况,并体会savepoint的作用。
1)实现以上功能的PL/SQL代码段如下所示
SQL> begin
2 update employees set salary = salary + 100; 3 savepoint salary100;
4 update employees set salary = salary + 200; 5 rollback to salary100; 6 commit; 7 end; 8 / 精品文档
· 252·
PL/SQL procedure successfully completed.
2)在该PL/SQL代码段中,首先利用savepoint salary100保存了回滚标记点,然后将员工工资增加了200。接着回滚到标记点,最后提交。可以利用select语句查看最终的工资信息只增加了100。
SQL> select salary from employees;
SALARY ---------- 3400 4400 4200 4400 3300 3100
6 rows selected.
3.新建会话1,并将其事务设置为串行化事务,然后,创建会话2。在会话1中尝试向表people插入新的数据,然后在会话2中也向表people插入新的数据,并提交。查看此时会话1中表people的数据状态,体会串行化事务的特点。
1)在command窗口中,利用sqlplus命令登录数据库,作为会话1。利用如下语句将当前事务设置为串行化事务
SQL> set transaction isolation level serializable;
Transaction set.
2)在会话1中向表people中插入id为20的新数据
SQL> insert into people values(20, '张三', 'ACT');
1 row created.
3)新建command窗口,并利用sqlplus登录数据库,作为会话2。在会话2中插入id为21的新数据,并提交。
SQL> insert into people values(21, '李四', 'ACT');
1 row created.
SQL> select * from people where id = 21;
ID NAME STA ---------- -------------------- ---
21 李四 ACT
SQL> commit;
Commit complete.
4)此时,在会话1中,查询id为20和21的记录。
SQL> select * from people where id = 20 or id = 21;
ID NAME STAUS
---------- -------------------- ------------ 20 张三 ACT 精品文档
·253·
5)这反映了串行化事务的特点:能够读写数据,但是会隔离其他事务对数据库状态的修改。
第20章 并发控制
1.利用悲观锁定首先锁定表people中id为1的记录,然后在另一会话中尝试更新这条记录,体会悲观锁定的作用。
1)在command中利用sqlplus登录数据库,并作为第一个会话。接着利用select…for update语句来锁定表people中id为1的记录。
SQL> select * from people where id=1 for update;
ID NAME STAUS
---------- ----------------- ---------------- 1 JamesACT
2)新建会话2,并尝试锁定表people中id为1的记录。
SQL> select * from people where id=1 for update;
3)会话2将会阻塞,这是因为会话1已经锁定了同一记录。除非会话1的事务结束,否则会话2将一直等待下去。
2.重复习题1的操作步骤,在会话2中锁定时利用nowait选项,以便锁定失败时立即返回错误。 1)在会话1中首先锁定表people中id为1的记录。
SQL> select * from people where id=1 for update;
ID NAME STAUS
---------- ----------------- ---------------- 1 JamesACT
2)在会话2中尝试锁定同一条记录,并增加nowait选项。
SQL> select * from people where id=1 for update nowait; select * from people where id=1 for update nowait * ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified
3)与习题1中的阻塞状态不同,会话2锁定失败,并立即返回错误消息。
3.在日常开发中,可能会出现数据表被锁定,而影响其他用户的情况。而锁定的原因往往较难发现,尤其是多用户共用同一数据库的情况下。此时,管理员可以通过结束会话的方式来释放对表的锁定。首先利用for update锁定表people,然后在会话2中获得锁定表people的会话id,最后通过alter system kill session命令来关闭会话。
1)在会话1中锁定表people
SQL> select * from people where id=1 for update;
ID NAME STATUS ---------- -------------------- --------------- 精品文档
· 254·
1 James ACT
2)在会话2中查询锁定表people的会话
SQL> select s.sid, s.serial#, o.object_name from v$session s, v$locked_object l, dba_objects o
2 where s.sid = l.session_id and l.object_id = o.object_id and object_name like '%PEOPLE%' 3 /
SESSION_ID SERIAL# OBJECT_NAME ---------------------------------------------------- 150 41 PEOPLE
3)在会话2中终止会话150
SQL> alter system kill session '150, 41';
System altered.
4)这里终止的实际是会话1,那么会话1再进行数据库操作,Oracle将抛出错误。
SQL> select userenv('sid') from dual; select userenv('sid') from dual *
ERROR at line 1:
ORA-00028: your session has been killed
第21章 Oracle中的正则表达式
1.利用regexp_instr()函数,在字符串“abc***123”中,查找第一次出现连续“*”的位置。
SQL> select regexp_instr('abc***123', '\\*+') result from dual;
RESULT ---------- 4
2.利用regexp_instr()函数,获得字符串“abc***123”中,第一次出现的连续“*”。
SQL> select regexp_substr('abc***123', '\\*+') result from dual;
RESULT --- ***
3.利用regexp_replace()函数将YYYY-MM-DD格式的字符串“2009-10-01,转换为MM/DD/YYYY格式。
SQL> select regexp_replace('2009-10-01', '([[:digit:]]{4})-([[:digit:]]{2})-([[:digit:]]{2})', '\\2/\\3/\\1') format_date from dual;
FORMAT_DATE ----------- 10/01/2009
精品文档
·255·
第22章 Oracle在Java开发中的应用
1.DBC连接Oracle数据库的字符串及字符串各参数的意义是什么?
JDBC连接Oracle数据库的字符串为,jdbc:oracle:thin:@host:port:sid。
jdbc表示连接方式为JDBC连接。所有的数据库连接字符串都以“jdbc”开始。 oracle代表数据库类型,表示要连接的数据库为Oracle数据库。
thin,代表Oracle的连接方式。Oracle有两种连接模式,一种是OCI连接,另外一种即为THIN连接。对于JDBC中的连接,一般使用THIN连接,因为这种连接方式简单易用,稳定性高。
@host,表示数据库所在的主机。在此,可以为主机IP或者局域网内的主机名称。 port,表示数据库监听端口。 sid,表示要连接的数据库SID。
2.简述利用Hibernate插入数据的主要操作步骤。 利用Hibernate向数据库中插入数据的主要步骤如下: (1)创建对象,例如:
people = new People()。
(2)组装对象,例如:
people.setName(\ people.setStatus(\
(3)保存对象,例如:
session.save(people);
第23章 Oracle在C#开发中的应用
1.简述C#中如何使用Oracle数据库事务。 (1)建立数据库连接
OracleConnection connection = new OracleConnection(connectionString;
(2)打开数据库连接
connection.Open()
(3)创建并启动一个数据库事务
OracleTransaction myOracleTransaction = connection.BeginTransaction();
(4)创建并执行数据库操作 (5)提交数据库事务
myOracleTransaction.Commit();
(6)关闭数据库连接
connection.close();
2.举例说明C#中对Oracle数据库进行事务处理的一般作法。
对Oracle数据库进行事务处理一般使用try-catch语句,来处理异常,并在finally子句中关闭数据
精品文档
· 256·
库连接,如下代码所示。
try {
//创建一个Oracle命令对象
OracleCommand myOracleCommand = myOracleConnection.CreateCommand();
//为myOracleCommand设置命令文本
myOracleCommand.CommandText = \
//进行数据库操作1
//进行数据库操作2
//进行数据库操作3 . .
.
//提交事务
myOracleTransaction.Commit();
//捕获异常
} catch(Exception ex) {
//回滚事务
myOracleTransaction.Rollback();
} finally {
//关闭数据库连接
connection.close(); }
精品文档