对XAF BO数据库连接可控

在项目后期演示系统功能时,由于数据库连接池耗尽导致数据库连接失败。报错信息显示为超时并达到最大池大小。问题出现在频繁创建和释放XPObjectSpaceProvider。初步分析在创建XAF XPObjectSpaceProvider100次后出现问题。解决方法包括全局复用XPObjectSpaceProvider和每次使用后及时释放数据库连接。具体选择取决于项目需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

某项目进行中,在项目前期数据库访问正常。在项目后期,尤其是演示系统功能时,在操作一段时间后系统出现数据库连接池不够导致数据库连接不成功。

报错信息:

DevExpress.Xpo.DB.Exceptions.UnableToOpenDatabaseException
  HResult=0x80131500
  Message=无法打开数据库。连接字符串:“data source=192.168.1.202;user id=sa;password=***REMOVED***;initial catalog=Set;Persist Security Info=true;”;错误:'System.InvalidOperationException: 超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。
   在 System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   在 System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   在 System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   在 System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
   在 System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
   在 System.Data.SqlClient.SqlConnection.Open()
   在 DevExpress.Xpo.DB.MSSqlConnectionProvider.CreateDataBase(SqlConnection conn)“

  Source=DevExpress.Xpo.v19.1
  StackTrace:
   在 DevExpress.Xpo.DB.MSSqlConnectionProvider.CreateDataBase(SqlConnection conn)
   在 DevExpress.Xpo.DB.MSSqlConnectionProvider.CreateDataBase()
   在 DevExpress.Xpo.DB.ConnectionProviderSql..ctor(IDbConnection connection, AutoCreateOption autoCreateOption)
   在 DevExpress.Xpo.DB.MSSqlConnectionProvider..ctor(IDbConnection connection, AutoCreateOption autoCreateOption)
   在 DevExpress.Xpo.DB.MSSqlConnectionProvider.CreateProviderFromString(String connectionString, AutoCreateOption autoCreateOption, IDisposable[]& objectsToDisposeOnDisconnect)
   在 DevExpress.Xpo.DB.DataStoreBase.QueryDataStore(String providerType, String connectionString, AutoCreateOption defaultAutoCreateOption, IDisposable[]& objectsToDisposeOnDisconnect)
   在 DevExpress.Xpo.XpoDefault.GetConnectionProvider(String connectionString, AutoCreateOption defaultAutoCreateOption, IDisposable[]& objectsToDisposeOnDisconnect)
   在 DevExpress.ExpressApp.Xpo.ConnectionStringDataStoreProvider.CreateWorkingStore(IDisposable[]& disposableObjects)
   在 DevExpress.ExpressApp.Xpo.XPObjectSpaceProvider.CreateObjectSpace(Func`1 objectSpaceDelegate)
   在 DevExpress.ExpressApp.Xpo.XPObjectSpaceProvider.CreateObjectSpace()
   在 SuperNest_DB_Test.Form1.button1_Click(Object sender, EventArgs e) 在 C:\Users\DELL\source\repos\SuperNest_DB_Test\SuperNest_DB_Test\Form1.cs 中: 第 52 行
   在 System.Windows.Forms.Control.OnClick(EventArgs e)
   在 System.Windows.Forms.Button.OnClick(EventArgs e)
   在 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   在 System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   在 System.Windows.Forms.Control.WndProc(Message& m)
   在 System.Windows.Forms.ButtonBase.WndProc(Message& m)
   在 System.Windows.Forms.Button.WndProc(Message& m)
   在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   在 System.Windows.Forms.Application.Run(Form mainForm)
   在 SuperNest_DB_Test.Program.Main() 在 C:\Users\DELL\source\repos\SuperNest_DB_Test\SuperNest_DB_Test\Program.cs 中: 第 19 行

  此异常最初是在此调用堆栈中引发的: 
    [外部代码]

内部异常 1:
InvalidOperationException: 超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。
 

数据库:MS SQL Server V2012

经过初步分析,在创建XAF XPObjectSpaceProvider 100次之后出现问题。

解决办法:

1、对XPObjectSpaceProvider做全局复用;

2、对XPObjectSpaceProvider每次使用后释放其数据库连接;

具体使用哪个方式,取决项目的特性。

分析代码:

using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Xpo;
using DevExpress.Xpo;
using System;
using System.Collections;
using System.Configuration;
using System.Windows.Forms;
using XSToolSet.Module.BusinessObjects;

namespace SuperNest_DB_Test
{
    public partial class Form1 : Form
    {
        String XSXafDBString;
        //数据库访问供应商提供者
        XPObjectSpaceProvider osProvider;
        //数据库的对象空间(每一个)
        IObjectSpace objectSpace;//SYS_User

        /// <summary>
        /// 
        /// </summary>
        public Form1()
        {
            InitializeComponent();

            //获取XPO信息源(必带)
            XpoTypesInfoHelper.GetXpoTypeInfoSource();

            //申明引用的数据对象
            XafTypesInfo.Instance.RegisterEntity(typeof(SYS_User));
            XafTypesInfo.Instance.RegisterEntity(typeof(SYS_UserRole));
            XafTypesInfo.Instance.RegisterEntity(typeof(SYS_Role));

            //给XPO的数据对象指定数据库链接字符串
            XSXafDBString = ConfigurationManager.ConnectionStrings["Set"].ConnectionString;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            for (int i = 0;i<20000;i++)
            {
                Console.WriteLine($"Create Connect :{i}");
                //创建数据库访问
                this.osProvider = new XPObjectSpaceProvider(@XSXafDBString, null);
                //获取到数据对象
                this.objectSpace = osProvider.CreateObjectSpace();

                if (objectSpace != null)
                {
                    objectSpace.Dispose();
                }

                IDataLayer datalayer = osProvider.DataLayer;
                if (datalayer.Connection != null)
                {
                    datalayer.Connection.Dispose();
                }

                if (osProvider != null)
                {
                    osProvider.Dispose();
                }
            }
            MessageBox.Show($"All done!");
        }

    }
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_16215957

如果有帮助一杯咖啡奶茶均可

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值