关于oracle database link,使用database link相关的查询语句是否会开启事务呢?我们知道,在数据库中一个简单的SELECT查询语句不会产生事务(select for update会产生事务)。如下测试所示:

我们首先准备测试环境,创建了一个database link: LINK_NODEFINE_TEST,然后我们开始测试

CREATE PUBLIC DATABASE LINK LINK_NODEFINE_TEST

CONNECT TO TEST IDENTIFIED BY "t123$%^" 

USING '(DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = TCP)(HOST = 10.20.57.24)(PORT = 1521))

    )

    (CONNECT_DATA =

      (SERVICE_NAME = gsp.localdomain)

    )

  )';

下面开始演示一下database link相关的查询是否会开启事务:

SQL> show user;

USER is "SYS"

SQL> select userenv('sid') from dual;

 

USERENV('SID')

--------------

           939

 

SQL> select xidusn, xidslot, xidsqn  

  2  from v$transaction, v$session  

  3  where saddr=ses_addr;

 

no rows selected

 

SQL> select * from kerry@link_nodefine_test;

 

        ID NAME

---------- --------------------------------

       100 kerry

 

SQL> select xidusn, xidslot, xidsqn  

  2  from v$transaction, v$session  

  3  where saddr=ses_addr;

 

    XIDUSN    XIDSLOT     XIDSQN

---------- ---------- ----------

         3         14    4122050

 

SQL> alter session close database link link_nodefine_test;

ERROR:

ORA-02080: database link is in use

 

 

SQL> commit; --必须要先commit,才能关闭链接

 

Commit complete.

 

SQL> alter session close database link link_nodefine_test;

 

Session altered.

下面我们创建一个账号TEST,测试验证database link所指向远程数据库中会话的生存周期,简单测试,你会发现即使一个简单查询(包含database link),会在远程数据库生成一个会话。而且如果不执行alter session close database link xxx关闭对应的database link的话,该会话不会销毁,而是变成INACTVIE状态。直到其触发了TCP keepalive相关机制后才会被数据库清理。

一旦你执行了database link相关的查询,  那么在远程数据库(10.20.57.24)这个测试服务器的数据库实例中,就会生成对应的会话,而且只有在原数据库执行了“alter session close database link link_nodefine_test"后,对应的会话才会销毁(当然,触发了TCP keepalive相关机制后也会被数据库清理)。有兴趣可以自行测试。

SQL> select count(*) from v$session where username='TEST';

 

  COUNT(*)

----------

         1

 

SQL> select count(*) from v$session where username='TEST';

 

  COUNT(*)

----------

         0

 

SQL> 

那么问题来了,如果我在会话当中多次使用select * from kerry@link_nodefine_test这类包含database link的语句,是否会在10.20.57.24生成多个会话呢? 还是说这个database link相关的会话会复用呢? 下面我们测试验证一下:

如下所示,同一个会话当中多次使用database link查询,不会在10.20.57.24生成多个会话。 但是如果多个不同会话中都使用database link link_nodefine_test的话,那么就会在(10.20.57.24)中生成多个会话

那么如果在同一个会话中,使用不同的database link,但是这两个database link使用相同的账号,指向相同的服务器,那么这个是否也共用一个会话呢?答案是不会,而是会生成新的会话。如下测试所示

CREATE PUBLIC DATABASE LINK LINK_DEDIATED_TEST

CONNECT TO TEST IDENTIFIED BY "t123$%^" 

USING '(DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = TCP)(HOST = 10.20.57.24)(PORT = 1521))

    )

    (CONNECT_DATA =

       (SERVER = DEDICATED)

      (SERVICE_NAME = gsp.localdomain)

    )

  )';

关于dblink的查询为什么产生事务的原理分析,参考官方文档Transaction Processing in a Distributed System

Two-Phase Commit Mechanism

A database must guarantee that all statements in a transaction, distributed or non-distributed, either commit or roll back as a unit. The effects of an ongoing transaction should be invisible to all other transactions at all nodes; this transparency should be true for transactions that include any type of operation, including queries, updates, or remote procedure calls.

The general mechanisms of transaction control in a non-distributed database are discussed in the Oracle Database Concepts. In a distributed database, the database must coordinate transaction control with the same characteristics over a network and maintain data consistency, even if a network or system failure occurs.

The database two-phase commit mechanism guarantees that all database servers participating in a distributed transaction either all commit or all roll back the statements in the transaction. A two-phase commit mechanism also protects implicit DML operations performed by integrity constraints, remote procedure calls, and triggers.

总结:

Oracle数据库中使用dblink的相关查询语句会产生事务, 如果有大量会话使用dblink的话,会在远程数据库产生大量的会话,有时候消耗的连接数量会非常可观。对于dblink在远程数据库的会话,必须先在本地数据库的当前会话commit,然后alter session close database link xxx, 关闭dblink,如果不执行这些操作,只能靠DCD或Tcp KeepLive机制触发数据库销毁会话。

参考资料:

https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:393468893370

http://blog.itpub.net/267265/viewspace-2123710/

https://docs.oracle.com/cd/B28359_01/server.111/b28310/ds_concepts004.htm#ADMIN12120

Oracle database link中查询会开启事务吗?的更多相关文章

  1. oracle Database Link

    1 Database Link 的创建: 有两个数据库服务器A/B, 其中A的IP地址为172.20.36.245, 服务器B为本机.服务器B上的数据库实例名为ORCL,在本机上的服务监听配置上有服务 ...

  2. Oracle DATABASE LINK(DBLINK)创建

    数据库全局名称可以用以下命令查出: SELECT * FROM GLOBAL_NAME; 修改可以用以下语句来修改参数值: ALTER SYSTEM SET GLOBAL_NAME=TRUE/FALS ...

  3. ora-01017 和oracle database link

    DB link ,创建完了后总是报密码错误.我感到奇怪.明明密码是对的.怎么可能错误呢. SQL> create public database link kk40 connect to khf ...

  4. Oracle Database Link 连接数据库复制数据

    --1. 创建dblink连接 create database link mdm66 connect to lc019999 identified by aaaaaa using '10.24.12. ...

  5. Oracle Database Link 的创建和使用小见

    假设:需要从数据库db_a通过db_link连接到db_b查询数据库b的部分相关信息 前提条件: 数据库a账户需要有创建dblink的权限,如果没有可以使用dba账户赋权限 grant CREATE ...

  6. 07 模型层 orm相关查询 F查询Q查询 django开启事务

    一.Django终端打印SQL语句 如果你想知道你对数据库进行操作时,Django内部到底是怎么执行它的sql语句时可以加下面的配置来查看 在Django项目的settings.py文件中,在最后复制 ...

  7. ORACLE与mysql中查询第n条到第m条的数据记录的方法

    ORACLE: SELECT * FROM             (                  SELECT 表名.*, ROWNUM AS CON FROM 表名 WHERE ROWNUM ...

  8. oracle Database link 创建

    http://www.cnblogs.com/yhason/p/3735319.html

  9. 事务的隔离级别,mysql中开启事务、django中开启事务

    目录 一.事务的特性 二.数据库中开启事务 三.Django中开启事务的两种方式 第一种 第二种 四.事务的隔离级别 隔离级别 如何查看mysql隔离级别? 修改事务的隔离级别 隔离级别解释 read ...

随机推荐

  1. Ceres配置(vs2013+Win10)

    主要参考文:Ceres Solver 在Windows下安装配置笔记 eigen.gflags.glog.suitesparse按照上面的链接中的指导配置即可. 配置ceres的时候,按照上面的链接内 ...

  2. JVM基础系列第2讲:Java 虚拟机的历史

    说起 Java 虚拟机,许多人就会将其与 HotSpot 虚拟机等同看待.但实际上 Java 虚拟机除了 HotSpot 之外,还有 Sun Classic VM.Exact VM.BEA JRock ...

  3. 查询运营商的ip段

    查询运营商的ip段 所有的IP地址都是通过国际组织NIC(Network Information Center)统一分配的,目前世界上有三个这样的网络信息中心: InterNic: 负责美国及其他地区 ...

  4. redis 系列9 对象类型(字符串,哈希,列表,集合,有序集合)与数据结构关系

    一.概述 在前面章节中,主要了解了 Redis用到的主要数据结构,包括:简单动态字符串.链表(双端链表).字典.跳跃表. 整数集合.压缩列表(后面再了解).Redis没有直接使用这些数据结构来实现键值 ...

  5. Service Fabric部署笔记

    使用 x509 证书时报错 Thumbprint contains invalid characters 原因是在 windows 证书管理器复制指纹的时候,在指纹字符串开头有不显示的字符,粘贴到 j ...

  6. Chapter 5 Blood Type——1

    The rest of the morning passed in a blur. 早上剩下的时间都在模糊中度过了. It was difficult to believe that I hadn't ...

  7. VS2015安装水晶报表

    最近在做一个打印功能,本来是不想用水晶报表的.想直接用微软原生的报表rdlc完成,但是整了一个上午老是打印乱码,且网上找资料找也找不出. 无奈放弃,然后就想到用水晶报表了,以前用过水晶报表,不过一直都 ...

  8. 小程序开发笔记【一】,查询用户参与活动列表 left join on的用法

    今天在做一个用户活动查询功能的时候,查询参与的活动.正常,使用egg-mysql查询数据一般会这么写 result = await this.app.mysql.select('tb_activity ...

  9. Perl线程队列:Thread::Queue

    (Thread::Queue)队列数据结构(FIFO)是线程安全的,它保证了某些线程从一端写入数据,另一些线程从另一端读取数据.只要队列已经满了,写入操作就自动被阻塞直到有空间支持写操作,只要队列空了 ...

  10. #12 Python函数

    前言 矩形的面积 S = ab,只要知道任一矩形的的长和宽,就可以带入上式求得面积.这样有什么好处呢?一个公式,适用于全部矩形,一个公式,重复利用,减少了大脑的记忆负担.像这类用变量代替不变量的思想在 ...