《WF编程》系列之43 - 承载工作流:持久性服务 Persistence Services

android persistent属性研究     为什么写这篇文章呢?前段时间在研究telephony时,一直没有在framework下发现对telephony的初始化(PhoneFactory.java中的makeDefaultPhones函数)的调用。结果全局搜索之后发现在application PhoneApp(packages/apps/Phone)中调用了。但是application PhoneApp既没有被Broadcast唤 阅读详情

工作流在长时间运行时难免会遇到一些问题,许多业务逻辑需要花费数日、数周乃至数月。在这段时间中,我们不能让工作流实例一直驻留在内存中(比如,我们需要一份开支报告,而不巧的是对此负责的会计师却在西班牙海滩休假,怎么办呢?)。在Windows Workflow中,可以通过持久化服务来解决长时间运行的工作流可能遇到的问题。

长时间运行的工作流耗费了大量的时间,却一直处于空闲状态。处于空闲状态的工作流可能在等待Delay活动完成,或者等待HandleExternalEvent活动的事件到达。当启用了持久化服务后,Runtime就可以将空闲的工作流持久化,然后从内存中卸载。当等待的事件到达后,Runtime再恢复工作流的执行。

什么时候来持久化工作流是由工作流Runtime决定的,而工作流状态将如何保存,还有保存到哪里则是由持久化服务决定的。空闲工作流是指没有任何活动处于执行状态的工作流,空闲工作流一般都在等待外部事件的到达或Delay活动的到期(当然,Delay活动的到期也可以看做是一种事件)。另外,当工作流满足以下条件时Runtime也会通知持久化服务去保存工作流状态:

  • 当TransactionScope活动内的原子性事物或CompensatableTransactionScopeActivity活动完成时
  • 当宿主应用程序调用WorkflowInstance对象的Unload或RequestPersist方法时
  • 当被PersistOnClosed特性修饰的自定义活动完成时
  • 当CompensatableSequence活动完成时
  • 当工作流终结或完成时

最后一个条件可能会有点奇怪,因为工作流完成或被终结之后就没有必要去重新加载工作流了,那么为什么还要保存状态呢?持久化服务可以使用这个机会去清空上一次操作遗留的工作流状态。持久化服务可以将工作流状态作为一条记录保存到数据库中,例如,在工作流完成后,持久化服务可以删除这条记录,也可以保留着完成状态的记录作为归档。

译者注: 针对最后一个条件解释一下,其实持久化服务并不是要求我们必须去在工作流完成后保存状态,他只是给我们在工作流完成后进行操作的能力,该进行什么操作由我们来决定,比如下面将要介绍的SqlWorkflowPersistenceService就选择了在工作流完成之后从数据库删除这条记录,而不是保存状态。

 

6.3.1 持久化类

所有持久化服务都从WorkflowPersistenceService类继承而来。如果我们需要编写自定义持久化服务的话,就需要实现这个类定义的抽象方法。这些抽象方法在下图中用斜体字表示。此外,基类还为子类提供了一些实例方法。例如,GetDefaultSerializedForm方法以活动作为参数并返回一个bytes数组来表示序列化后的活动。如果需要序列化整个工作流,你只需要将工作流的根活动传递给这个方法。
 

Windows Workflow提供了一个现成的持久化服务 – SqlWorkflowPersistenceService。SQL持久化服务将工作流状态保存到Microsoft SQL Server数据库中,接下来我们来认识一下它。

 

6.3.2 SqlWorkflowPersistenceService

想要使用SQL持久化服务,我们还需要一个数据库。我们可以使用已经存在的数据库,或者创建一个新的数据库。创建数据库的方法有好多,比如企业管理器、查询分析器、SQL Server 2005的SQL Server Management Studio、SQL Server 2005的命令行工具sqlcmd.exe和SQL Server 2000的osql.exe。当数据库创建后,我们需要运行Windows Workflow SQL持久化服务的脚本来创建持久化服务需要的数据库对象。这些脚本位于Windows Workflow安装目录中(也就是.NET 3.0 Runtime安装目录中):
C:/WINDOWS/Microsoft.NET/Framework/v3.0/Windows Workflow Foundation/SQL/EN。
需要执行的SQL脚本有两个:SqlPersistenceService_Schema.sql和SqlPersistenceService_Logic.sql。首先执行schema脚本来创建表和索引,然后再执行Logic脚本来创建一些存储过程。下图演示了如何使用sqlcmd.exe创建持久化服务数据库。首先我们创建数据库,然后通过sqlcmd.exe加:r参数来运行两个脚本。
 

6.3.3 SQL 持久化服务配置

当我们创建好了正确的数据库,我们就可以为工作流Runtime添加持久化服务了。我们将使用配置文件来定义服务:

<? xml version="1.0" encoding="utf-8"  ?>
 
< configuration >
   
< configSections >
   
< section  name ="WorkflowWithPersistence"
   type
="System.Workflow.Runtime.Configuration.WorkflowRuntimeSection, System.Workflow.Runtime,Version=3.0.00000.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35" />
   
</ configSections >
   
< WorkflowWithPersistence >
   
< CommonParameters >
   
< add  name ="ConnectionString"  
   value
="Data Source=.;Initial Catalog=c6ps;Integrated Security=True" />
   
</ CommonParameters >
   
< Services >
   
< add  type ="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"  
   UnloadOnIdle
="true"   />
   
</ Services >
   
</ WorkflowWithPersistence >
 
</ configuration >

持久数据库连接字符串位于CommonParameters节中,这样做的好处是可以将连接字符串共享给其它需要连接该数据库的服务。在Services节中的SqlWorkflowPersistenceService节包含一些参数来调整服务的行为。本例中,我们只配置了一个参数 – UnloadOnIdle。它的其它参数如下表所示:
 

 参数名称 描述
EnableRetries 当值为true时,服务会重试失败的数据库操作,重试次数为20次或者一直重试到操作成功。默认值为false。
 LoadIntervalSeconds 服务检查过期定时器的间隔时间。默认值是120秒。
OwershipTimeoutSeconds当持久化服务加载工作流时,锁死工作流记录的时间长度(这一点在当多个Runtime公用相同的持久化服务数据库时相当重要)。默认值为TimeSpan.MaxValue。
UnloadOnIdle当设置为true时,服务会持久化并从内存中卸载空闲的工作流。默认值是false。

 

6.3.4 运行持久化服务

我们将使用如下的工作流定义来是持久化服务生效: 

< SequentialWorkflowActivity  x:Class ="Chapter6_PersistenceService. WorkflowWithDelay"  
   x:Name
=" WorkflowWithDelay"  
   xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"  
   xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/workflow" >
  
< CodeActivity  x:Name ="codeActivity1"  ExecuteCode ="codeActivity_ExecuteCode"   />
  
< DelayActivity  TimeoutDuration ="00:00:10"  x:Name ="delayActivity1"   />
  
< CodeActivity  x:Name ="codeActivity2"  ExecuteCode ="codeActivity_ExecuteCode"   />
 
</ SequentialWorkflowActivity >

在两个Code活动之间有一个Delay活动。Delay活动会让工作流空闲10秒钟。在后台代码中,两个Code活动的ExecuteCode事件都引用了同一个事件处理器,用来控制台窗口中输入简单的信息。

namespace  Chapter6_PersistenceService
 {
   
public   partial   class  WorkflowWithDelay: SequentialWorkflowActivity
  {
   
private   void  codeActivity_ExecuteCode( object  sender, EventArgs e)
   {
   CodeActivity activity 
=  sender  as  CodeActivity;
   Console.WriteLine(
" Hello from {0} " , activity.Name); 
   }
   }
 }

接着,我们订阅一些事件并让宿主程序运行工作流。

public   class  Persist
 {
 
public   static   void  Run()
 {
   
using  (WorkflowRuntime runtime  =   new  WorkflowRuntime( " WorkflowWithPersistence " ))
   
using  (AutoResetEvent reset  =   new  AutoResetEvent( false ))
   {
   runtime.WorkflowCompleted 
+=   delegate  { reset.Set(); };
   runtime.WorkflowTerminated 
+=   delegate  { reset.Set(); };
   runtime.WorkflowPersisted 
+=
   
new  EventHandler < WorkflowEventArgs > (
   runtime_WorkflowPersisted);
   runtime.WorkflowLoaded 
+=
   
new  EventHandler < WorkflowEventArgs > (
   runtime_WorkflowLoaded);
   runtime.WorkflowUnloaded 
+=
   
new  EventHandler < WorkflowEventArgs > (
   runtime_WorkflowUnloaded);
   runtime.WorkflowIdled 
+=
   
new  EventHandler < WorkflowEventArgs > (
   runtime_WorkflowIdled);
   WorkflowInstance instance;
   instance 
=  runtime.CreateWorkflow( typeof (WorkflowWithDelay));
   instance.Start();
   reset.WaitOne();
   }
 }

 
static   void  runtime_WorkflowIdled( object  sender, WorkflowEventArgs e)
 {
   Console.WriteLine(
" Workflow {0} idled " ,
   e.WorkflowInstance.InstanceId);
 }

 
static   void  runtime_WorkflowUnloaded( object  sender, WorkflowEventArgs e)
 {
   Console.WriteLine(
" Workflow {0} unloaded " ,
   e.WorkflowInstance.InstanceId);
 }

 
static   void  runtime_WorkflowLoaded( object  sender, WorkflowEventArgs e)
 {
   Console.WriteLine(
" Workflow {0} loaded " ,
   e.WorkflowInstance.InstanceId);
 }

 
static   void  runtime_WorkflowPersisted( object  sender, WorkflowEventArgs e)
 {
   Console.WriteLine(
" Workflow {0} persisted " ,
   e.WorkflowInstance.InstanceId);
 }
 }

宿主应用程序通过配置文件创建了新的Runtime,然后订阅了一些工作流事件来向控制台窗口中输出信息。当上面的代码执行完后,我们的实例程序将如下图所示:
 
第一个Code活动执行后,在控制台中输出了信息。然后Delay活动阻止了工作流。Runtime发现工作流已经没有可执行的操作就触发了WorkflowIdled事件。同时Runtime还发现持久化服务被启用了,而且该服务被配置为UnloadOnIdle,于是Runtime通知持久化服务去保存工作流的状态,然后卸载了工作流实例。当Delay活动过期后,Runtime使用持久化服务来重新加载工作流实例并恢复执行。
当SQL持久化服务重新加载了工作流之后,服务会在数据库中标记实例为锁死状态。如果其它进程的持久化服务或者其它计算机想要加载这个工作流,服务就会抛出异常。锁的作用就是防止工作流实例在两个不同的Runtime中运行。当工作流再一次被持久化后,或者锁超时后(可以通过OwnershipTimeoutSeconds设置锁死长度),锁就会被解开。
当工作流完成后,Runtime再一次通知持久化服务去持久化工作流。SqlWorkflowPersistenceService在对工作流进行“考察”后,发现工作流确实已经完成了执行过程。这时服务并不会保存当前状态,而是会删除上一次保存的状态记录。在持久化服务数据库中,大多数的数据库操作发生在InstanceState表中。
持久化服务保存工作流状态时,第一个工作就是将工作流序列化。为了更好的理解持久化服务,我们再来看看WF中的序列化。

 

6.3.5 持久化和序列化

在Windows Workflow中有两种类型的序列化。Runtime提供了WorkflowMarkupSerializer类来将工作流转换为XAML。标记语言序列化器并不关心工作流内部的数据,也不需要保存状态。它的目的仅仅是为设计工具和代码生成器生成XML格式的工作流定义。
而持久化服务所使用的是另外一种序列化方式,持久化服务通过使用WorkflowPersistenceService类的GetDefaultSerializeForm方法来序列化工作流。这个方法调用了Activity类的Save方法,Save方法通过使用BinaryFormatter对象(二进制格式化器)来序列化工作流。二进制格式化器会生成一个字节流,WorkflowPersistenceService会通过GZipStream来压缩这个字节流。二进制序列化的目的是生成工作流实例的紧凑的表现形式,然后用来长时间存储。现在我们知道了Windows Workflow中有两种不同类型的序列化器,但它们的功能却不重复,因为从根本上来说,它们的应用场景和目的就是不一样的。
我们没有必要去理解完整的序列化细节,重要的是要知道当持久化工作流时,Runtime会使用BinaryFormatter类。如果我们需要编写如下的工作流的话,更加需要牢记这一点:

public   partial   class  WorkflowWithDelay2 : SequentialWorkflowActivity
 {
   Bug _bug 
=   new  Bug();
 }
 
class  Bug
 {
   
private  Guid _id;
   
public  Guid BugID
   {
   
get  {  return  _id; }
   
set  { _id  =  value; }
   }
 }

假设这个工作流除了和上面的示例一样包含一个Delay活动之外,还包含一个私有的Bug对象。哪怕我们对Bug对象并不感兴趣,它也会改变持久化行为。如果我们不启用持久化服务,那么这个工作流会成功的完成。但如果我们启用了持久化服务,我们就会发现一个异常:Type Bug is not marked as serializable。 
BinarryFormatter会尝试序列化工作流状态信息的所有内容,当然也包括这个自定义的Bug对象。当任何对象格式化器(object formatter)发现需要序列化的对象时,它首先会查看该对象类型是否注册了代理选择器(surrogate selector)。如果没有代理选择器,格式化器就会查看Type是否标记了Serializable特性。如果这些条件都不满足,格式化器就会停止工作并抛出异常。Bug类是我们自己添加的类,我们可以用Serializable特性来装饰它,藉此来避免发生异常。

[Serializable]
 
class  Bug
 {
   
private  Guid _id;
   
public  Guid BugID
   {
   
get  {  return  _id; }
   
set  { _id  =  value; }
   }
 }

如果Bug类是第三方提供的,我们可以编写一个代理选择器来完成序列化,不过这已经超出了本章讨论的范畴(关于SurrogateSelector类的更多细节请查看System.Runtime.Serialization命名空间)。
如果有一些字段并不需要和工作流实例一起序列化和恢复,我们就可以通过NonSerialized特性来告诉格式化器跳过它。在下面的代码中,Bug对象就不会被序列化。当Runtime重新加载了工作流后,_bug字段又会变成初始状态。

public   partial   class  WorkflowWithDelay2 : SequentialWorkflowActivity
 {
   [NonSerialized]
   Bug _bug 
=   new  Bug();
 }

持久化服务保存工作流状态,并允许我们重启计算机和长时间的运行工作流。但是,持久化服务并不能告诉我们在工作流的执行过程中发生了什么,或者工作流已经进行多久了。我们的下一个主题 – 跟踪服务会给予我们这方面的信息。

译者注: 关于持久化,园子里还有几位朋友的文章也相当不错,推荐阅读:

Proteus课设原理图及报告 1. I/O 口:32 个可编程 I/O 引脚,分成 4 个并行 I/O 端口 (P0, P1, P2, P3),P0 功能段选 a、b、c、d、e、f、g、dp 使其中部分点亮,P2 功能为位选 1、2、4.按键操作分析:P3.0-设置时钟的时间,P3.1-确定更改的时钟时间,P3.2-对。时钟设置标志 0 不设置,1 设置时,2 设置分,3 设置秒。P3.0 按下的次数对应 不设置,设置时,设置分, 阅读详情

相关推荐

AD9026芯片开发实战指南:从硬件配置到射频校准

本文为AD9026芯片开发实战指南,详细解析了从硬件设计、电源时钟配置、SPI初始化到多芯片同步与JESD204高速链路建立的完整流程。重点探讨了射频校准技术,包括初始化校准与跟踪校准,以保障5G、MIMO等现代通信系统所需的射频性能。旨在帮助开发者系统掌握这颗高性能射频收发器的应用,规避常见设计陷阱。

tomato的博客 851

《WF编程》系列之43 - 工作流宿主:持久化服务 Persistence Services

《WF编程》系列之43 - 工作流宿主:持久化服务 Persistence Services 工作流在长时间运行时难免会遇到一些问题,许多业务逻辑需要花费数日、数周乃至数月。在这段时间中,我们不能让工作流实例一直驻留在内存中(比如,我们需要一份开支报告,而不巧的是对此负责的会计师却在西班牙海滩休假,怎么办呢?)。在Windows Workflow中,可以通过持久化服务来解决长时间运行的...

weixin_30657541的博客 227

FLoRA: 基于异构低秩适应的联邦微调大语言模型

大语言模型(LLMs)的快速发展推动了人工智能的进步,预训练的LLMs可以通过微调适应各种下游任务。联邦学习(FL)通过利用客户端的本地数据进行原位计算,进一步增强了隐私保护的微调,消除了数据移动的需求。然而,考虑到LLMs的巨大参数量,微调LLMs对于资源受限且异构的FL客户端来说是一个挑战。之前的方法采用了低秩适应(LoRA)进行高效的联邦微调,但在LoRA适配器上使用了传统的FL聚合策略。这些方法导致了数学上不准确的聚合噪声,降低了微调效果,并且未能解决异构LoRA的问题。

tiger00O的博客 2066

浅析 自定义PersistenceService类

转载并用C#语言重写,文章很简单,学习用 该例自定义了一个将实例持久化到磁盘文的操作,分两部分第一部分是实现PersistenceService类,第二部分是操作磁盘的功能类 实现PersistenceService类   using System;using System.Collections.Generic;using System.Linq;using System.Te...

回忆,是眼睛里的海 508

INMP441麦克风与ESP32的I2S音频采集实战指南

本文提供了INMP441数字麦克风与ESP32开发板通过I2S接口进行高质量音频采集的完整实战指南。详细讲解了硬件连接、软件配置、数据读取及基础处理,并分享了常见的避坑技巧与性能优化建议,帮助开发者快速构建物联网音频应用。

weixin_28396629的博客 598

OpenVINS实战指南:从环境搭建到RGB-D相机实时建图

本文提供了一份详细的OpenVINS实战指南,涵盖从Ubuntu与ROS环境搭建、依赖安装与编译调试,到连接RGB-D相机进行实时建图的完整流程。重点解决了RealSense D435i等设备的驱动配置、话题对齐及常见问题,并分享了传感器标定与性能优化技巧,帮助开发者快速实现稳定高效的视觉惯性里程计系统。

weixin_29201313的博客 484

SqlPersistenceService持久化数据库

1.1  数据库安装<br />系统盘/Windows/Microsoft.NET/Framework/v3.0/Windows Workflow Foundation/SQL/EN下<br />SqlPersistenceService_Schema.sql<br />SqlPersistenceService_Logic.sql<br /> 1.2  数据库时间格式说明<br />在SqlPersistenceService数据库中,时间值是GMT格式的,<br />这样做的目地是使用统一的时间轴,<b

学无止境 2080

mcgs数据导出到U盘

mcgs触摸屏在工业中应用还是很多的,尤其他的脚本功能策略功能等将开放性放到了最大,让用户可以根据实际需求进行自由创作,正因为这样,对一些初学者就不是很友好,初学者想要简单操作就能实现功能,但是mcgs不可能两者兼备,在做工业设备,一些数据的采集保存就比较常见,但是mcgs没有相关按钮能够直接实现将数据导出到U盘的功能。这里我给大家讲解关于mcgs将报警历史记录、日志记录、历史数据记录导出到U盘的方法。

qq_24866535的博客 6235

Rust Qt Binding Generator性能优化:提升Rust与Qt交互效率的10个技巧

Rust Qt Binding Generator是一个强大的工具,它能够生成绑定代码,让Rust代码与Qt GUI框架无缝交互。通过优化Rust Qt绑定生成器的使用方式,您可以显著提升应用程序的性能和响应速度。本文将为您介绍10个实用的性能优化技巧,帮助您充分发挥Rust的内存安全性和Qt的GUI优势。🎯 ## 1️⃣ 理解绑定生成器的工作原理 Rust Qt Binding Gener

gitblog_00147的博客 1067

ASIC--DFT可测性设计工程师

DFT是什么? DFT是design for test(可测性设计)的缩写,就是在芯片设计过程中,加入可测性逻辑。有的公司把该职位归到前端设计,有的归到中端实现。 DFT职位大多分布于规模较大的数字IC设计公司里,因为大公司对芯片品质要求高,而且规模越大,芯片越贵,DFT就越复杂越重要。DFT主要是通过在芯片中加入可测性逻辑,等芯片制造出来,在ATE(AutomaticTestEquipmen...

TroubleMaker 2万+

超级详细的GNS3最新版3-2.2.50安装配置教程,网工速度收藏!

你好,这里是网络技术联盟站,我是瑞哥。上周给大家分享了GNS3安装包。周末的时候有小伙伴在安装的时候遇到了一些问题,瑞哥周末特地从头安装了一下GNS3,今天给大家出个安装的教程,每一步的步骤我都截图了下来,希望对大家有所帮助!

网络技术联盟站 1109

.NET Framework 4.0 和 "Dublin" 中的 WCF 和 WF 服务 - z

在 2008 年 10 月份召开的专业开发人员大会(PDC) 上,Microsoft 发布了有关 Microsoft .NET Framework 4.0 中将要提供的大量改进的详细信息,尤其是在 Windows Communication Foundation (WCF) 和 Windows Workflow Foundation (WF) 领域。Microsoft 还首次公开了对 Win...

weixin_30454481的博客 188

《网络安全自学教程》- Nmap使用及扫描原理分析

使用Nmap进行端口扫描、主机发现、服务识别、操作系统识别、指定脚本、结果导出文件,使用wireshark抓包分析扫描原理。

wangyuxiang946的博客 1万+

应用系统端口的统一设计(一)

本设计不通用,只针对特定的一类问题。 如果系统经常和多种端口打交道,例如:COM,TCP,UDP,短信,打印机等等外接端口通讯,那么可以这样设计。 每种通讯方式都是类似,连接,打开端口,接收和发送数据,解析数据给系统。 所以可以统一起来进行设计,这样扩充端口更加容易。 使用C#语言描述 [code="c#"] public delegate void GameEve...

qixin000的专栏 528

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Nacos源码之一-配置自动更新(重写)

Nacos 是阿里巴巴开源的集分布式配置中心、分布式注册中心为一体的分布式解决方案。 它的优点: 提供命令空间,方便管理不同环境的配置; 提供web界面,方便管理配置和服务; 支持配置版本管理,回滚; 支持服务管理,手动上线、下线服务。 等等其他优点。 1 如何使用 Nacos 自动更新配置 1.1 配置自动更新的两种方式 第一种方式 属性使用@Value注解 类使用@RefreshScope 注解 @RefreshScope @RequestMapping("config") public

伍六七的博客 2037

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

SqlPersistenceService数据库结构

  数据库安装 系统盘\Windows\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\EN下 SqlPersistenceService_Schema.sql SqlPersistenceService_Logic.sql 数据库时间格式 数据库时间格式说明 在SqlPersistenceService数据库...

weixin_33911824的博客 156

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Persistent service

<br />一般情况下,程序运行时,数据和对象是有效的;当程序结束的时候,就会消失。如果数据要被永久的存储,那么在ABAP 对象里就使用persistent services.这些服务就写当前的属性值到数据库里,一收到另外一个请求就将他们的值从表里导出来,写到一个永久服务里,这个永久服务就是使用OPEN SQL的接口。<br />为一个对象使用persistent service,就需要使用persistent class, persistent class是唯一的,需要包含key attributes.使

george_506的专栏 1324

定义permission, 使用新定义的permission, persist service

AndroidManifest.xml: Declares a security permission that can be used to limit access to specific components or features of this or other applications.             android:icon="drawable

u011279649的专栏 1175

Workflow4 持久化之数据库模型

概述 在没有持久化之前,流程实例只能在内存中短期运行,一旦流程需要长期运行,这就需要预先将工作流保存并在将来重新加载,也就是工作流的持久化。Workflow 4(WF4)将工作流持久化作为一个可选的插件来提供持久化的服务,并通过调用SqlWorkflowPersistenceService类来实现SQL Server数据中Workflow的持久化。 工作原理 工作流持久化通过开启工作流持

heshengfen123的专栏 3028

持久化日志LogPersist类

前言:        项目做了一部分,要有持久化日志这一功能。目的是方便以后建库。项目后台预设了访问记录,登录记录等功能,但是一期还没有写到这个地方,所以需要做一些持久化信息的操作,一方面方便记录信息,一方面也要为以后建库提供数据;        因为以后这些数据是要建库的,所以样式什么的也不能随便写。所以也就封装了一个工具类,便于做这些日志信息或者建库之前数据的持久化;        当然了,这...

zFox的博客 1433

Weblogic连接池泄漏排查

1、查看Weblogic 的控制台,发现可用数量为02、查看日志,报错,获取不到连接Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is weblogic.jdbc.extensions.PoolLimitSQL...

专注于java,站在巨人头顶看世界 7698

Android 5.0 以下Native进程保活尝试

Android 5.0 以下版本的Native保活机制

superxlcr的博客 2717

持久化服务:EntityManager

实体即POJO(Entities Are POJOs)在java Persistence规范中,实体即普通的Java对象(POJO)。和其它普通Java对象一样,你只需使用new()运算符就可以为其分配内存。托管与非托管实体(Managed Versus Unmanaged Entities)若entity bean与EntityManager相关联,则EntityManager会跟踪

linshi8126的专栏 559

Android设置蓝牙地址到persist.service.bdroid.bdaddr

//函数property_set需要包含头文件#include <cutils/properties.h> int android_set_btaddr_into_property(char *addr) { return property_set("persist.service.bdroid.bdaddr", addr); } int main() { typede...

sui1005316018的博客 1190
上一篇: Microsoft Windows Workflow Foundation 入门:开发人员演练
下一篇: DataGridView选中行的值
thy822
博客等级 码龄19年 313粉丝 294原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值