当前位置: 代码迷 >> .NET新技术 >> 关于wcf事宜的使用
  详细解决方案

关于wcf事宜的使用

热度:428   发布时间:2016-04-25 01:23:55.0
关于wcf事务的使用
先贴代码,服务端方法:
[OperationBehavior(TransactionAutoComplete=true,TransactionScopeRequired=true)]
        [TransactionFlow(TransactionFlowOption.Allowed)]
        public string SaveCardLoss(string token, string strOperate, string strSaveData) {
            System.Transactions.Transaction myTran = System.Transactions.Transaction.Current;
            string strJsonResult = "";
            int iResult = 0;
            Message myMessage = new Message();
            try
            {
                #region 验证令牌
                userTOtoken ut = TokenManage.tokenmanager.Instance.TokenQuery(token);
                if (ut == null)
                {
                    return "noToken";
                }
                #endregion
                List<CardLoss> listCardLoss = JsonConvert.DeserializeObject<List<CardLoss>>(strSaveData);
                using (var myDb = new LFACSDB<CardLoss>(LFACSDB<CardLoss>.GetConn))
                {
                    switch (strOperate)
                    {
                        case "add":
                            listCardLoss.ForEach(delegate(CardLoss item)
                            {
                                myMessage.CreateDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                                myMessage.CreateUser = ut.user_code;
                                item.CreateDate = myMessage.CreateDate;
                                item.CreateUser = myMessage.CreateUser;
                                iResult = myDb.Insert(item);
                                myMessage.ResultInfo = item.AutoID.ToString();
                            });
                            break;
                        case "edit":
                            listCardLoss.ForEach(delegate(CardLoss item)
                            {
                                item.ModiDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                                item.ModiUser = ut.user_code;
                                myMessage.ResultInfo = myDb.Update(item).ToString();
                            });
                            break;
                        case "del":
                            listCardLoss.ForEach(delegate(CardLoss item)
                            {
                                myMessage.ResultInfo = myDb.Delete(item).ToString();
                            });
                            break;

                    }
                }
                strJsonResult = JsonConvert.SerializeObject(myMessage);
            }
            catch (Exception ex) { throw ex; }
            return strJsonResult;
        }

客户端代码:
 using (System.Transactions.TransactionScope myTran = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required))
            {
                using (AccessService.AccessServiceClient myClient = new AccessService.AccessServiceClient())
                {
                    if (strOperas == "add" || strOperas == "edit" || strOperas == "del")
                    {

                        string strsaveData = context.Request.Form["saveData"];
                        strResult = myClient.SaveCardLoss(token, strOperas, strsaveData);
                        myTran.Complete();  //提交事务
                        context.Response.Write(strResult);

                    }}}

这里的问题是,事务还没有提交, myTran.Complete(); //提交事务,为什么数据库就可以查询数据出来了呢?按照事务隔离的概念,事务没有提交的话,数据是查询不出来的,会处于等待的状态,请兄弟们回答哦.......
------解决思路----------------------
wcf的事务跟数据库里的事务是有差别的,数据库事务是通过锁阻止其它sql请求,wcf不可能也不允许出现这样的情况,因为wcf根本不知道用户什么时候会执行Complete或者其它指令
------解决思路----------------------
具体怎么得忘了……wcf的书不是我的……
wcf的事务我觉得只是一个约束性的东西,然后包含提交和回滚的概念,具体怎么操作是要有相应的实现
------解决思路----------------------
不提倡是因为事务会阻塞数据库请求啊,在wcf事务中,只要客户端不执行rollback或者commit,那数据库就要一直被阻塞,影响其它操作
------解决思路----------------------
引用:
这里的问题是,事务还没有提交, myTran.Complete(); //提交事务,为什么数据库就可以查询数据出来了呢?按照事务隔离的概念,事务没有提交的话,数据是查询不出来的,会处于等待的状态,请兄弟们回答哦.......


没有怎么看你的代码,仅针对这个说法回答一下。

事务中当然可以读数据,如果不读数据,你如何进行计算啊。比如说一个事务是“把银行A账户的利息结算完成,然后A账户的一笔汇款的手续费结算出来并从A账户上转给银行,成功以后再把这笔汇款从A账户转到B账户”,这事务中必然需要查询的。必然是要在事务之中(而不是之外)去进行查询的,不查询就不存在一个真正有意义的事务了。

所谓“隔离”是指针对“其它会话”的隔离,不是对所有人(一个会话自己)也一样处理。
------解决思路----------------------
引用:
Quote: 引用:

不提倡是因为事务会阻塞数据库请求啊,在wcf事务中,只要客户端不执行rollback或者commit,那数据库就要一直被阻塞,影响其它操作


但是在有些业务情况下我就需要阻塞数据库请求,具体原因我不说你肯定懂的......


事务开始之后,才查询数据(事务开始之前的查询数据不算数),然后才知道如何更改数据库。事务操作本来就是这样的。

难道你以前都是在开始事务之前去查询,然后开始事务之后立刻去更新?那么你可真是错误地使用事务了。
------解决思路----------------------
我给你重复确认一下:

在事务开始之前查询计算到的数据,全都不算数。在事务开始之后重新进行查询,然后进行计算,然后持久化保存起来。

这才是事务。
------解决思路----------------------
引用:
肯定是事务之外的不能查询了,这个是没有疑问的,请教您在wcf事务中是怎么做的,能不能具体点,最好贴下代码学习下......


我没有看你的代码。按照你这个说法,事务之外不能查询,然后“事务还没有提交myTran.Complete();,数据库也不可以查询数据出来”,那么你到底是想什么时候查询数据呢?这是自相矛盾的了。

这类东西不用抄别人的代码。就是学一个基本的概念而已。
------解决思路----------------------
数据库的事务“隔离”,比如说,当你的会话启动了一个事务,当你在事务中开始查询时,你的事务就在你查询过的记录上对其它事务申请了一组“禁止读”锁。

我没有看你的代码(代码太多了)。但是从你的描述上看,你没有直接了当地描述你的问题的“前提条件”。

在一个会话中使用 TransactonScope 而不使用数据库事务是不能保证有什么数据库事务存在的。即使你可能真的对 TransactionScope提交了,但是它可能根本就跟数据库无关,你的代码可能根本就没有通知它对哪一个数据库启动事务。这个“提交”就是毫无意义的。因此我们通常不用这个玩意儿,而是直接使用数据库事务语法,这样可以保证确实是在用具体的数据库事务(而不是TransactionScope。

然后就算是你确实启动了两个数据库会话并且在一个启动了数据库事务,如果你在事务中根本没有读数据也不修改数据,也不会对其它事务产生“读锁”的效果。那么这种事务也是毫无意义的,不可能去影响别的事务读取任何数据。
------解决思路----------------------
引用:
我以前也是直接在服务方法里写数据库事务,但是我在一本wcf书里(那本书还是比较权威的)看到说不提倡在wcf服务方法里使用数据库事务哦,而要这样使用wcf的事务,那怎么解释呢??大哥,有没有qq向你请教,QQ:524120915


transactionscope不是什么wcf事务。根本没有“wcf事务”这个概念。transactionscope是一个抽象的、没有什么内容的,用于“所有事务”的统一接口。
  相关解决方案