首页 新闻 会员 周边

与当前连接相关联的事务已经完成,但尚未释放。必须先释放该事务,然后才能使用该连接来执行 SQL 语句

0
悬赏园豆:120 [已解决问题] 解决于 2014-07-02 22:28

开发环境:使用的WCF4.0+ SL

 

事务控制:使用WCF自带事务参数控制

[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)].

 

由于程序处理时,时间大概>=10分钟,报错。

宝宝,爸爸爱你的主页 宝宝,爸爸爱你 | 初学一级 | 园豆:57
提问于:2014-07-01 22:20
< >
分享
最佳答案
0

把那些 Timeout 都设置大于 10 分钟。

收获园豆:120
Launcher | 高人七级 |园豆:45045 | 2014-07-02 08:50

早上好!

 

我是这样设置的,您看下.

SL :

 

 1 <configuration>
 2   <system.serviceModel>
 3     <bindings>
 4       <basicHttpBinding>
 5         <binding name="BasicHttpBinding_WcfService" closeTimeout="00:01:00"
 6           openTimeout="00:01:00" receiveTimeout="01:00:00" sendTimeout="01:00:00"
 7           maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
 8           <security mode="None" />
 9         </binding>
10       </basicHttpBinding>
11     </bindings>
12     <client>
13       <endpoint address="http://localhost/XXXX/WCFService/WcfService.svc"
14         binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_WcfService"
15         contract="WcfServiceClient.WcfService" name="BasicHttpBinding_WcfService" />
16     </client>
17   </system.serviceModel>
18 </configuration>

 

服务器端:

 1  <behaviors>
 2       <serviceBehaviors>
 3         <behavior name="">
 4           <serviceMetadata httpGetEnabled="true" />
 5           <serviceDebug includeExceptionDetailInFaults="false" />
 6           <dataContractSerializer maxItemsInObjectGraph="2147483647" />
 7           <serviceTimeouts transactionTimeout="01:00:00" />
 8         </behavior>
 9       </serviceBehaviors>
10     </behaviors>
11     <bindings>
12       <basicHttpBinding>
13         <binding name="LargeDataTransferServicesBinding"
14                  maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
15         </binding>
16         <binding name="BasicHttpBinding_WcfService" closeTimeout="00:01:00"
17        openTimeout="00:01:00" receiveTimeout="01:00:00" sendTimeout="01:00:00"
18        maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
19           <readerQuotas maxStringContentLength="2147483647"/>
20           <security mode="None" />
21         </binding>
22       </basicHttpBinding>
23     </bindings>
宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-02 09:04

外加服务端的这个设置:

1   <system.transactions>
2     <defaultSettings timeout="01:00:00"/>
3   </system.transactions>

 

宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-02 09:05

@宝宝,爸爸爱你: 你是如何使用 SQL 事务的?

Launcher | 园豆:45045 (高人七级) | 2014-07-02 09:07

@Launcher: 我没有使用SQL事务,使用的是WCF的事务控制。

 

SQL执行如下:

 1  DataTable dtRt = null;
 2 
 3             try
 4             {
 5                 SqlCommand cmd = new SqlCommand(strSql, sqlConn);
 6                 cmd.CommandType = CommandType.Text;
 7                 cmd.CommandTimeout = 1800;
 8                 SqlDataAdapter da = new SqlDataAdapter(cmd);
 9                 dtRt = new DataTable();
10                 da.Fill(dtRt);
11                 return dtRt;
12             }
13             catch (Exception ex)
14             {
15                 throw ex;
16             }
宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-02 09:22

@宝宝,爸爸爱你: 你的 sqlConn 在哪儿实例化的?

Launcher | 园豆:45045 (高人七级) | 2014-07-02 09:23

@Launcher: 在构造函数中实例化的

 

Code :

  

 1  private SqlConnection sqlConn = null;
 2 
 3 /// <summary>
 4         /// 构造函数
 5         /// </summary>
 6         /// <param name="baseInfo">日志信息</param>
 7         public SqlHelper(BaseInfo baseInfo)
 8         {
 9             //连接字符串
10             string conString = ConfigurationManager.AppSettings["SQLServerDBConnStr"].ToString();
11             sqlConn = new SqlConnection(conString);
12             logCon = new SqlConnection(conString);
13             this.baseInfo = baseInfo;
14         }
宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-02 09:35

@宝宝,爸爸爱你: 改成函数的局部变量,使用完即释放。

Launcher | 园豆:45045 (高人七级) | 2014-07-02 09:40

@Launcher: 

  关键是,我的业务处理还没有完成,这时,SqlConnection还不能释放,但是WCF事务已经完成了。

宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-02 09:43

@宝宝,爸爸爱你:你能给我举一个列子说明“业务处理还没有完成,SqlConnection还不能释放”吗?

Launcher | 园豆:45045 (高人七级) | 2014-07-02 09:44

@Launcher: 

 

  现在我conn.Open(),

    

  由于使用WCF控制,我还不确定,什么时候开启的事务。

 

  在处理业务数据,对数据进行业务检查,需要执行SQL文

 

  WCF事务自动完成

 

  conn.CLose() 

 

  以上为正常流程。

  异常流程就出现了:由于业务数据检查耗时长,导致了WCF事务关闭先执行了。

宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-02 09:51

@Launcher: 

  以上说法有点错误哈,

 

  按照提示的错误信息来看:

与当前连接相关联的事务已经完成,但尚未释放。必须先释放该事务,然后才能使用该连接来执行 SQL 语句

应该是我连接先关闭了,但是WCF事务没有释放,但是在查看连状态是 Open 的。

宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-02 09:55

@宝宝,爸爸爱你: 你这表达能力太差了,你还是把你的那个标记了事务的 wcf 服务类源码给贴出来吧。

Launcher | 园豆:45045 (高人七级) | 2014-07-02 09:56

@Launcher: 

 

  WCF :

  

 1 [OperationContract]
 2         [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
 3         public int IPO0101_SaveInfos(
 4             BaseInfo baseInfo,
 5             ObservableCollection<IPO0101DTO> oceInputEntity,
 6             ObservableCollection<string> ocsRelatedEngine,
 7             out string logFilePath)
 8         {
 9             IPO0101Business myBussiness = new IPO0101Business();
10             return myBussiness.SaveInfos(
11                 baseInfo,
12                 oceInputEntity,
13                 ocsRelatedEngine,
14                 out logFilePath);
15         }
View Code

 

 业务处理:

 1 public int SaveInfos(
 2             BaseInfo baseInfo,
 3             ObservableCollection<IPO0101DTO> oceInputEntity,
 4             ObservableCollection<string> ocsRelatedEngine,
 5             out string logFilePath)
 6         {
 7             //创建连接数据库方法
 8             SqlHelper con = new SqlHelper(baseInfo);
 9             List<SqlParameter> sqlParmlist = new List<SqlParameter>();
10             SqlParameter para = new SqlParameter();
11             string sql;
12             string SQL = "";
13             DataTable existDT = new DataTable();
14             DataTable DTComper = new DataTable();
15             con.Open();
16             int intMaxID = 0;
17             //int virtualID = 1;
18 
19            //......................................................
20           //  此处为业务处理,多次调用了SQL执行
21           //  在执行的过程中,给出了错误提示
22           // ......................................................
23 
24             con.Close();
25             return rtCode;    
View Code
宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-02 10:04

@宝宝,爸爸爱你: 假设有 5 次调用 SQL 执行,提示错误总是在第几次给出,还是经过多长时间间隔就会给出?

Launcher | 园豆:45045 (高人七级) | 2014-07-02 10:13

@Launcher:  

  的确总会在一个位置上提示错误,时间是10分钟~13分钟 

     

宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-02 10:15

@宝宝,爸爸爱你: Timeout 的问题,<behavior name=""> 给个名字,然后给服务指定上

Launcher | 园豆:45045 (高人七级) | 2014-07-02 11:48

@Launcher: 

  指定服务,您说的是哪个服务,

  现已指定的TimeOut : 

  <serviceTimeouts transactionTimeout="01:00:00" />

  <defaultSettings timeout="01:00:00"/>

  

宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-02 12:28

@宝宝,爸爸爱你: 

<services>
      <service behaviorConfiguration="NewBehavior" name="Learn.Library.WCF.MyService">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8080/MyService" />
          </baseAddresses>
        </host>
        <endpoint address="" binding="basicHttpBinding"
          contract="Learn.Library.WCF.IContract" />
        <endpoint address="mex" binding="mexHttpBinding"
          contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="NewBehavior">
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

Launcher | 园豆:45045 (高人七级) | 2014-07-02 13:01

@Launcher: 

按照您的代码调整我的配置文件,

 

报错:在服务 WcfService 实现的协定列表中找不到协定名称 "IMetadataExchange"。将 ServiceMetadataBehavior 添加到配置文件或直接添加到 ServiceHost,以启用对该协定的支持。

宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-02 15:45

@Launcher: 

 1  <behaviors>
 2       <serviceBehaviors>
 3         <behavior name="WebApp.WCFService.WcfService">
 4           <serviceMetadata httpGetEnabled="true" />
 5           <serviceDebug includeExceptionDetailInFaults="false" />
 6           <dataContractSerializer maxItemsInObjectGraph="2147483647" />
 7           <serviceTimeouts transactionTimeout="01:00:00" />
 8         </behavior>
 9       </serviceBehaviors>
10     </behaviors>
11     <bindings>
12       <basicHttpBinding>
13         <binding name="LargeDataTransferServicesBinding"
14                  maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
15         </binding>
16         <binding name="BasicHttpBinding_WcfService" closeTimeout="00:01:00"
17        openTimeout="00:01:00" receiveTimeout="0:01:00" sendTimeout="01:00:00"
18        maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
19           <readerQuotas maxStringContentLength="2147483647"/>
20           <security mode="None" />
21         </binding>
22       </basicHttpBinding>
23     </bindings>
24     <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
25       multipleSiteBindingsEnabled="true" />
26     <services>
27       <service name="WebApp.WCFService.WcfService">
28         <host>
29           <baseAddresses>
30             <add  baseAddress="http://localhost/XXXX/WCFService/WcfService.svc"/>
31           </baseAddresses>
32         </host>
33         <endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_WcfService"
34           contract="WebApp.WCFService.WcfService" />
35         <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
36       </service>
37     </services>
View Code

加上了服务名称。

宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-02 15:48

@宝宝,爸爸爱你: <host>.....</host> 就不要了,<endpoint address="mex"...../> 也删除掉

Launcher | 园豆:45045 (高人七级) | 2014-07-02 15:51

@Launcher: 

大神这样,还是不行,依然报错。

宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-02 16:02

@宝宝,爸爸爱你: 你给 wcf 服务配置个日志,然后把日志贴出来。

Launcher | 园豆:45045 (高人七级) | 2014-07-02 16:02

@Launcher:  是不是这个?

宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-02 16:08

@宝宝,爸爸爱你: 网上翻翻,有没有别的错误。

Launcher | 园豆:45045 (高人七级) | 2014-07-02 16:09

@Launcher: 

  上面的都是几天前执行的,同一个错误提示。

宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-02 16:11

@宝宝,爸爸爱你: 

[ServiceBehavior(TransactionTimeout = "01:00:00")]

class P001001_Saveinfos

Launcher | 园豆:45045 (高人七级) | 2014-07-02 16:16

@Launcher: 

 

  有这样一个问题,我没有描述:

  就是在foreach 循环中,循环次数 6000+

  循环过程中,执行了20+的数据库操作

  循环完成就需要执行 6000 * 20 的数据库操作。

  

  我判断不出这个的影响,就没有说。

宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-02 16:24

@宝宝,爸爸爱你: 你提的这个现象只是涉及到事务的容量问题,不太确定有关,你可以放到下面的代码中测试下:

using (System.Transactions.TransactionScope myTransaction = new
System.Transactions.TransactionScope(TransactionScopeOption.RequiresNew, newTimeSpan(0, 0, 0, 10, 250)))
            {

 

}

Launcher | 园豆:45045 (高人七级) | 2014-07-02 16:29

@Launcher: 

这个是否需要更新WCF ?

 

没有更新WCF ,还是报错,WCF日志还是一样。

宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-02 16:42

@Launcher: 

 

  嗯,好的,我先用声明的事务测试下。

 

  

宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-02 16:42

@宝宝,爸爸爱你: 

在配置文件中添加这个:

  <system.transactions>
    <machineSettings maxTimeout="01:00:00"/>
    <defaultSettings timeout="01:00:00"/>
  </system.transactions>

Launcher | 园豆:45045 (高人七级) | 2014-07-02 17:19

@Launcher: 

  不好意思,回复晚了。

  这个配置,我测试下。

  测试后,给答案。  

  现在调整了事务处理,使用SQL事务,不使用WCF事务了。

  谢谢您的解答。

宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-02 21:01

@Launcher: 

 

  测试测试,还是不行。

宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-02 22:27

@宝宝,爸爸爱你: <machineSettings maxTimeout="01:00:00"/> 这个添加在 Machine.Config 中,x86 和 x64 的都要添加。从 .Net 4 开始 TransactionScope 的 Timeout就不允许代码指定了,所以这样的语句(TransactionScope(TransactionScopeOption.RequiresNew, newTimeSpan(1,0,0)))不会起作用,Timeout 还是按照最大 10 分钟来设定。

Launcher | 园豆:45045 (高人七级) | 2014-07-03 09:14

@Launcher: 

  您好!

 

  您说的machine.config 配置IIS吗?

宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-03 09:26
Launcher | 园豆:45045 (高人七级) | 2014-07-03 09:36

@Launcher: 

  谢谢。

宝宝,爸爸爱你 | 园豆:57 (初学一级) | 2014-07-03 09:44
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册